我想在Windows操作系统上使用C编程语言打印以下ASCII字符:
的数据
#include <stdio.h> int main() { for(unsigned int ch=128 ; ch < 256 ; ch++) { printf("%d = %c\t\t", ch, ch); } return 0; }
字符串在输出中,我看到字符没有显示:
输出
的这可能是编码相关的问题。我怎样才能解码这些字符,使它们正确显示?
ftf50wuq1#
正如一些评论者所提到的,这不是ASCII。ASCII表在127处停止。它没有进一步。然而,其他一些表,如Unicode表,其条目从0到127与ASCII相同,但在此之后添加更多字符。所以为了给予你一个明确的答案,“我如何打印128到255个ASCII字符?””,则不能,因为没有值大于127的ASCII字符。现在,让我们深入研究您发送的表格。
在DOS时代,在1991年Unicode发布之前,微软提出了所谓的Code Pages。不像一个非常流行的观点,“扩展ASCII”不是ASCII表的扩展,而是ASCII表的扩展家族。代码页是ASCII扩展,Unicode也是。它们是以ASCII开头的字符表,然后添加自己的条目。回到历史课上,Microsoft代码页存在不同的迭代。如果您在Windows上打开命令提示符(cmd)并输入命令chcp,它将打印当前编码。默认情况下,在Windows 10和11上,它是Code Page 850。
Code Pages
chcp
您发送的ASCII扩展表是Code Page 437,正如评论员@ikegami所指出的那样。与Unicode不同,代码页不是通用的,它们仅适用于Windows。现代系统使用UTF-8,这是一种编码Unicode字符的方式,可以最大限度地减少文本所需的字节数。
我会马上避免给你错误的希望:没有一种通用的方法可以使你所要求的编码工作。你只能让它在Windows上工作,而且只有当你使用Windows的命令提示符(或PowerShell)。在您发送的屏幕截图中,您显然正在使用类似Linux的终端或shell。你将永远无法得到你在这种事情中要求的ASCII扩展名。
通过输入chcp 437命令,它会将命令提示符的编码更改为代码页437。请注意,这是暂时的,如果您打开一个新的CMD窗口,它将返回到默认编码,这是代码页850如上所述。然后,如果我们执行你嵌入的示例C代码,我们在这里:x1c 0d1x的数据但是告诉人们你可能会把你的代码分发给:“嘿,顺便说一下,打开Windows CMD并键入chcp 437,然后才使用该CMD示例运行我的工具,因为使用另一个示例将无法工作。”因此,您可以使用Windows API自动更改:
chcp 437
#include <stdio.h> #include <windows.h> int main() { SetConsoleOutputCP(437); for(unsigned int ch = 128; ch < 256; ch++) { printf("%d = %c\t\t", ch, ch); } return 0; }
字符串
#ifdef
编译后,如您所见,即使我将CMD的编码设置为代码页850,代码页437中的字符也会显示出来:的然而,这个解决方案只是…如果你打算让你的工具只在Windows上运行,我想这是可以的,但是使用非通用的字符集和编码通常是一个不好的做法。此外,如前所述,这个技巧将只有工作,如果你使用Windows的CMD(或Windows PowerShell,这也工作)。如果您使用的终端像您发送的屏幕截图中所做的那样,它将无法工作,因为所有终端和shell都使用UTF-8。
UTF-8是一种编码Unicode字符的方法,最好的是,它是通用的。所有终端都使用UTF-8,但如果您要求,Windows的CMD也可以使用。使用Windows API,您可以将CMD或PowerShell编码更改为UTF-8:
#include <windows.h> int main() { SetConsoleOutputCP(65001); // ... return 0; }
型
此外,当你在C代码中编写原始字符串时,无论如何,它们都会被编译器编码为UTF-8。这使得以下成为可能:
#include <stdio.h> #include <windows.h> int main() { SetConsoleOutputCP(65001); printf("Here is an accented character: é\n"); return 0; }
的看到了吗?我在代码中直接写入了一个不属于ASCII表的字符,并且成功打印出来了。当然,你不会有你在问题中要求的值,但是调整你的字符代码是一个很低的代价,可以使你的代码完全通用。此外,如果你想像你一样使用终端/shell,这是你唯一的解决方案。
如果你真的,绝对需要的字符表,你已经把你的问题:
型如果你不介意,只要你可以使用任何不在常规ASCII表中的字符,然后移动到UTF-8,这是通用的,比你想使用的更实用:
#include <stdio.h> #include <windows.h> int main() { SetConsoleOutputCP(65001); for(unsigned int ch = 128; ch < 256; ch++) { printf("%d = %c\t\t", ch, ch); } return 0; }
1条答案
按热度按时间ftf50wuq1#
简介
正如一些评论者所提到的,这不是ASCII。
ASCII表在127处停止。它没有进一步。然而,其他一些表,如Unicode表,其条目从0到127与ASCII相同,但在此之后添加更多字符。
所以为了给予你一个明确的答案,“我如何打印128到255个ASCII字符?””,则不能,因为没有值大于127的ASCII字符。
现在,让我们深入研究您发送的表格。
Microsoft和ASCII扩展名:代码页
在DOS时代,在1991年Unicode发布之前,微软提出了所谓的
Code Pages
。不像一个非常流行的观点,“扩展ASCII”不是ASCII表的扩展,而是ASCII表的扩展家族。
代码页是ASCII扩展,Unicode也是。它们是以ASCII开头的字符表,然后添加自己的条目。
回到历史课上,Microsoft代码页存在不同的迭代。如果您在Windows上打开命令提示符(cmd)并输入命令
chcp
,它将打印当前编码。默认情况下,在Windows 10和11上,它是Code Page 850。发送内容
您发送的ASCII扩展表是Code Page 437,正如评论员@ikegami所指出的那样。
与Unicode不同,代码页不是通用的,它们仅适用于Windows。现代系统使用UTF-8,这是一种编码Unicode字符的方式,可以最大限度地减少文本所需的字节数。
您的问题解决方案
我会马上避免给你错误的希望:没有一种通用的方法可以使你所要求的编码工作。你只能让它在Windows上工作,而且只有当你使用Windows的命令提示符(或PowerShell)。
在您发送的屏幕截图中,您显然正在使用类似Linux的终端或shell。你将永远无法得到你在这种事情中要求的ASCII扩展名。
将命令提示符编码改为代码页437(不可持续)
通过输入
chcp 437
命令,它会将命令提示符的编码更改为代码页437。请注意,这是暂时的,如果您打开一个新的CMD窗口,它将返回到默认编码,这是代码页850如上所述。
然后,如果我们执行你嵌入的示例C代码,我们在这里:x1c 0d1x的数据
但是告诉人们你可能会把你的代码分发给:“嘿,顺便说一下,打开Windows CMD并键入
chcp 437
,然后才使用该CMD示例运行我的工具,因为使用另一个示例将无法工作。”因此,您可以使用Windows API自动更改:
字符串
#ifdef
指令,以确保仅在Windows上编译Windows API相关的行。*编译后,如您所见,即使我将CMD的编码设置为代码页850,代码页437中的字符也会显示出来:
的
然而,这个解决方案只是…如果你打算让你的工具只在Windows上运行,我想这是可以的,但是使用非通用的字符集和编码通常是一个不好的做法。
此外,如前所述,这个技巧将只有工作,如果你使用Windows的CMD(或Windows PowerShell,这也工作)。
如果您使用的终端像您发送的屏幕截图中所做的那样,它将无法工作,因为所有终端和shell都使用UTF-8。
迁移到UTF-8(推荐)
UTF-8是一种编码Unicode字符的方法,最好的是,它是通用的。
所有终端都使用UTF-8,但如果您要求,Windows的CMD也可以使用。
使用Windows API,您可以将CMD或PowerShell编码更改为UTF-8:
型
#ifdef
指令,以确保仅在Windows上编译Windows API相关的行。*此外,当你在C代码中编写原始字符串时,无论如何,它们都会被编译器编码为UTF-8。这使得以下成为可能:
型
的
看到了吗?我在代码中直接写入了一个不属于ASCII表的字符,并且成功打印出来了。
当然,你不会有你在问题中要求的值,但是调整你的字符代码是一个很低的代价,可以使你的代码完全通用。
此外,如果你想像你一样使用终端/shell,这是你唯一的解决方案。
结论/ TL; DR
如果你真的,绝对需要的字符表,你已经把你的问题:
型
如果你不介意,只要你可以使用任何不在常规ASCII表中的字符,然后移动到UTF-8,这是通用的,比你想使用的更实用:
型
#ifdef
指令来执行仅限Windows的操作。*