【问题标题】:What are good methods in printing Extended ASCII characters for C?为 C 打印扩展 ASCII 字符的好方法是什么?
【发布时间】:2018-12-26 09:45:15
【问题描述】:

首先我想看看 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;
}

上面的两个代码 sn-ps 工作得很好,告诉我关于 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 字符?

【问题讨论】:

  • 无符号字符的最大值是多少?不是 256。
  • unsigned char a --> unsigned aint a
  • 无法保证 C 实现/环境完全使用 ASCII。
  • 要使字符有意义,您应该记住您正在使用的扩展 ASCII 字符集。 “扩展 ASCII”是某些字符编码的特征,但您一次只能使用一种字符编码..

标签: c loops character ascii extended-ascii


【解决方案1】:

您有一个无限循环,因为 unsigned char 可表示的最大值是 2551,并且将其递增超过该点会导致它回绕为零,因此条件 a &lt; 256 是总是正确的。如果您改用int,您的程序将按预期运行:

#include <stdio.h>
int main(void)
{
    for (int a = 128; a < 256; a++)
        printf("a=%c\n", a); 
    return 0;
}

int 传递给printf 的%c,2 完全没问题,只要它的unsigned char 可表示的范围内,即是的。

但是,如果您在现代计算机上运行此程序,您仍然可能会得到“奇怪的字符”。例如,当我在我的计算机上运行它时,我得到 128 行

a=�

这是因为现代计算机的 CLI 窗口需要 UTF-8 编码的 Unicode 文本,而在 UTF-8 中,U+007F 以上的所有字符都使用超过一个字节进行编码。因此,终端仿真器每行接收一个它认为无效的、不完整的字节序列,并为它们打印一个特殊的“替换字符”。查看 U+0080..U+00FF 范围内 实际 字符的最简单方法是使用 C 的“宽字符”:

#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;
}

wprintf 负责将宽字符转换为环境期望的任何文本编码。这不能保证有效,因为 C 的“宽字符”未指定且设计不良,以至于我实际上建议人们不要在生产代码中使用它们(相反,只使用包含 UTF 的窄字符串-8),但是对于这样的测试程序,您通常可以摆脱它。我得到这样的输出:

U+0080 = ''
U+0081 = ''
U+0082 = ''
...
U+00A0 = ' '
U+00A1 = '¡'
U+00A2 = '¢'
...
U+00FD = 'ý'
U+00FE = 'þ'
U+00FF = 'ÿ'

如果您的计算机不够现代,您可能会得到不同的东西。 U+0080..U+009F 范围是更多无用的控制字符,这就是为什么它们没有显示任何内容。


1 从技术上讲,[0, 255] 是unsigned char 所需的最小值范围; C 标准允许它可以代表更大的范围,例如[0, 511]。如果您在unsigned char 具有该范围的计算机上运行您的程序,它就会工作。然而,多年来没有人制造过这样的计算机。如果您真的想担心它,请包含 &lt;limits.h&gt; 并验证 CHAR_BIT 是 8 和/或 UCHAR_MAX 是 255。

2 从技术上讲,由于 C 的“默认参数提升”的残留特性,您总是int 传递给 %c,即使变量你提供的有一个字符类型。

【讨论】:

    【解决方案2】:

    这个

    a < 256
    

    总是true,因为unsigned char 有效范围是。

    【讨论】:

      【解决方案3】:

      循环

      for (unsigned char a = 128; a < 256; a++)
      

      由于unsigned 类型的环绕,255 + 1 为0,因此永远在您的平台上运行。你可以使用令人困惑的(当你第一次看到它时)

      for (unsigned char a = 128; a >= 128; a++)
      

      打印到您的控制台的内容将取决于您的系统使用的编码可能 ASCII),以及您的终端如何打印该范围内的字符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-12
        相关资源
        最近更新 更多