首先,我想看看C语言中ASCII可打印字符的样子。
以下是我的代码:
#include <stdio.h>
int main(void)
{
for (char a = 32; a < 127; a++)
printf("a=%c\n", a);
return 0;
}
#include <stdio.h>
int main(void)
{
for (unsigned char a = 32; a < 127; a++)
printf("a=%c\n", a);
return 0;
}
上面的两个代码段可以很好地工作,告诉我有关ASCII可打印字符的信息。
接下来,我想看看C的扩展ASCII字符。
#include <stdio.h>
int main(void)
{
for (unsigned char a = 128; a < 256; a++)
printf("a=%c\n", a);
return 0;
}
然后是未知字符未知的无尽循环。
我在哪里做错了?
我认为当a达到256时,循环将停止,但并没有。
奇怪的字符是从哪里来的?
如何为C打印扩展ASCII字符?
答案 0 :(得分:2)
您有一个无限循环,因为unsigned char
可以表示的最大值是255 1 ,并且将其递增到该点以上将导致其回绕为零,因此条件{{ 1}}始终是正确的。如果您改用a < 256
,则程序将按预期运行:
int
最好将#include <stdio.h>
int main(void)
{
for (int a = 128; a < 256; a++)
printf("a=%c\n", a);
return 0;
}
传递给printf的int
, 2 ,只要其 value 处于{可表示的范围内{1}}。
但是,如果您在现代计算机上运行此程序,您仍然可能会获得“奇怪的字符”。例如,当我在计算机上运行它时,我得到128行
%c
这是因为现代计算机的CLI窗口期望使用UTF-8编码的Unicode文本,并且在UTF-8中,U + 007F以上的所有字符都使用一个以上的字节进行编码。因此,终端仿真器每行接收一个它认为无效,不完整的字节序列,并为它们打印一个特殊的“替换字符”。在U + 0080..U + 00FF范围内查看实际字符的最简单方法是使用C的“宽字符”:
unsigned char
a=�
负责将宽字符转换为环境期望的任何文本编码。这不能保证能正常工作,因为C的“宽字符”没有经过充分指定且设计不当,以至于我实际上建议人们在生产代码中不使用它们(相反,只能使用持有UTF的狭窄字符串) -8),但是对于这样的测试程序,您通常可以免除它。我得到这样的输出:
#include <wchar.h>
#include <locale.h>
int main(void)
{
setlocale(LC_ALL, "");
for (int a = 128; a < 256; a++)
wprintf(L"U+%04X = '%lc'\n", a, (wchar_t)a);
return 0;
}
如果您的计算机不够现代,则可能会有所不同。 U + 0080..U + 009F范围是更多无用的控制字符,这就是为什么这些字符什么都没有显示的原因。
1 从技术上讲,[0,255]是wprintf
所需的最小范围; C标准允许它代表更大的范围,例如[0,511]。如果您在U+0080 = ''
U+0081 = ''
U+0082 = ''
...
U+00A0 = ' '
U+00A1 = '¡'
U+00A2 = '¢'
...
U+00FD = 'ý'
U+00FE = 'þ'
U+00FF = 'ÿ'
具有该范围的计算机上运行程序,则可以正常运行。但是,多年来没有人制造过这样的计算机。如果您真的要担心它,请添加unsigned char
并验证unsigned char
为8和/或<limits.h>
为255。
2 从技术上讲,由于C的一种残余功能(称为“默认参数提升”),您总是将CHAR_BIT
传递给UCHAR_MAX
,即使您提供的变量具有字符类型。
答案 1 :(得分:1)
此
a < 256
始终为true
,因为unsigned char
的有效范围为<0,255>。
答案 2 :(得分:0)
循环
for (unsigned char a = 128; a < 256; a++)
由于类型为unsigned
,因此255 + 1为0,因此会在您的平台上永久运行。您可以使用令人困惑的内容(第一次看到它时)
for (unsigned char a = 128; a >= 128; a++)
打印到控制台的内容将取决于系统使用的 encoding (可能是 ASCII),以及终端如何在该范围内打印字符。