如何打印128到255个ASCII字符?

41zrol4v  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(150)

我想在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;
}

字符串
在输出中,我看到字符没有显示:

输出



这可能是编码相关的问题。
我怎样才能解码这些字符,使它们正确显示?

ftf50wuq

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自动更改:

#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指令,以确保仅在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:

#include <windows.h>

int main() {
    SetConsoleOutputCP(65001);

    // ...

    return 0;
}

  • 您也可以选择使用#ifdef指令,以确保仅在Windows上编译Windows API相关的行。*

此外,当你在C代码中编写原始字符串时,无论如何,它们都会被编译器编码为UTF-8。这使得以下成为可能:

#include <stdio.h>

#include <windows.h>

int main() {
    SetConsoleOutputCP(65001);

    printf("Here is an accented character: é\n");

    return 0;
}



看到了吗?我在代码中直接写入了一个不属于ASCII表的字符,并且成功打印出来了。
当然,你不会有你在问题中要求的值,但是调整你的字符代码是一个很低的代价,可以使你的代码完全通用。
此外,如果你想像你一样使用终端/shell,这是你唯一的解决方案。

结论/ TL; DR

如果你真的,绝对需要的字符表,你已经把你的问题:

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


如果你不介意,只要你可以使用任何不在常规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;
}

  • 当然,只有在为Windows编译时,您才可以使用#ifdef指令来执行仅限Windows的操作。*

相关问题