我仍然在try C语言,以了解它是如何工作的.

打印扩展ASCII表(128-255)中的字符时遇到问题.如果我打印printf("Â")(例如),它就会打印(一切正常).但是,如果我给变量赋值,比如a = 194,然后打印变量printf("%c",a),它会打印�,而不是打印.

顺便说一句,它可以很好地处理32-127个字符(例如35个Print#)

->如何从整数(十进制或二进制)打印128-255个字符中的一个?任何帮助都将不胜感激.

我在Ubuntu 20.04.1 LTS上使用gcc11.3

推荐答案

您的编译器和终端很可能都使用UTF-8对非ASCII字符进行编码.

字符集和编码是一个庞大的主题,有许多不同和不兼容的约定和实现.在诸如ISO8859-1Windows-1252的传统单字节编码上,Â实际上被编码为194.它也是UNICODE标准中的字符数字,它有Â000多个不同的代码点,代表世界上几乎每一种语言和符号集.

有不同的方法将这些字符表示为字节序列,其中最普遍的是UTF-8,在99%的网页中使用.32-127范围内的ASCII字符表示为单字节,码点较大的字符使用2-4字节之间的字符,C2-F4范围内的前导字节和80-BF范围内的1-3个尾随字节.Â被编码为C3 82,这意味着"Â"实际上是与"\xC3\x82"相同的2字节字符串.

您可以使用以下代码验证这一点:

#include <stdio.h>
#include <string.h>

int main(void) {
    const char *s = "Â";
    int len = strlen(s);
    printf("%s: len=%d, bytes=", s, len);
    for (int i = 0; i < len; i++) {
        printf("%02hhX%c", s[i], " \n"[i == len - 1]);
    }
    return 0;
}

输出应为Â: len=2, bytes=C3 82.

要在输出流上将非ASCII字符转换为UTF-8序列,您可以使用<locale.h>和宽字符输出中的区域设置函数:

    setlocale(LC_ALL, "en_US.UTF-8");
    printf("%lc\n", 194);

输出:

Â

如果在终端中正确配置了区域设置,则可以 Select 默认区域设置setlocale(LC_ALL, "");

C++相关问答推荐

使用sd-设备列举设备导致seg错误

不同到达时间的轮询实现

C语言编译阶段与翻译阶段的关系

预先分配虚拟地址空间的区域

struct -未知大小

使用sscanf获取零个或多个长度的字符串

GTK3按钮信号错误

如何确保在C程序中将包含uft8字符的字符串正确写入MySQL?

一旦运行长度超过2,编译器是否会优化";strnlen(mystring,32)>;2";以停止循环?

如何用c语言修改shadow文件hash部分(编程)?

MacOS下C++的无阻塞键盘阅读

无法访问共享目标文件内的共享指针

覆盖读取函数,但当文件描述符为3或4时,我有问题

使用正则表达式获取字符串中标记的开始和结束

当我将偏移量更改为任何非零值时,C中的mmap共享内存出现无效参数错误

std::malloc/calloc/realloc/free 与纯 C 的 malloc/calloc/realloc/free 有什么不同

使用 GCC 将一个函数中初始化的 struct 体实例通过指针传递到 C 中的另一个函数会产生不同的结果

为什么程序在打印每个数字之前要等待所有输入?

如何在 C 中编辑 struct 体中的多个变量

Zig 中 C 的system函数的惯用替代方案