C中的无符号字符未按预期工作

Posted

技术标签:

【中文标题】C中的无符号字符未按预期工作【英文标题】:unsigned char in C not working as expected 【发布时间】:2021-08-17 19:05:20 【问题描述】:

由于 unsigned char 表示 0 - 255,而 'à' 的扩展 ascii 代码是 133,我希望下面的 C 代码打印 133

unsigned char uc;

uc='à';

printf("%hhu \n",uc);

相反,clang 和 gcc 都会产生以下错误

error: character too large for enclosing character literal type
uc='à';
    ^ 

出了什么问题?

顺便说一句,我从法语网站复制了 à 并将结果粘贴到赋值语句中。我怀疑我创建 à 的方式可能无效。

【问题讨论】:

您的编辑器使用的是 UTF-8 编码,而不是扩展的 ASCII。 您的编译器很可能将您的源代码视为 UTF-8 而不是 ASCII。而在 UTF-8 中,字母“à”表示为两个字节序列 0xC3 0xA0,因此不适合 char,无论是有符号还是无符号。 字符 à 不能在 C 程序中使用。尝试使用 \x85。 @YvesDaoust 你有规范参考的链接吗? 没有“扩展 ascii”这样的东西。有些人在一两年前用这个词来表示几个不相容的东西。今天没有理由使用它。 【参考方案1】:

因为 unsigned char 代表 0 - 255

在大多数实现中都是如此,但 C 标准不要求 char 限制为 8 位,它可以更大并支持更大的范围。

'à'的扩展ASCII码是133,

可能有一个 C 实现,其中 'à' 的值为 133 (0x85),但由于大多数实现使用 Unicode,'à' 可能使用最有可能存储为 UTF-8 的代码点 224 (0xE0)。您的编辑器也设置为 UTF-8,因此需要多个字节来表示 ASCII 以外的字符。在 UTF-8 中,所有 ASCII 字符都像 ASCII 一样存储,需要 1 个字节,所有其他字符都是 2-4 个字节的组合,并且每个字符都设置了第 7 位。我建议您了解 UTF-8 的工作原理,UTF-8 是大多数情况下存储文本的最佳方式,因此您应该仅在有充分理由时才使用其他方式。

我希望下面的 C 代码打印 133

在 UTF-8 中,à 的代码点存储为 0xC3 0xA0,组合成值 0xE0。您不能将 0xC3 0xA0 存储在 8 位 char 中。所以clang报错。 您可以尝试将其存储在intunsignedwchar_t 或其他一些足够大的整数类型中。 GCC 将存储值 0xC3A0 而不是 0xE0,因为这是 '' 中的值。但是,C 支持宽字符。 wchar_t 可能支持更多字符的类型很可能wchar_t 在您的系统上是 32 或 16。要编写宽字符文字,您可以使用前缀 L。使用宽字符文字,编译器将存储正确的值 0xE0。

将代码改为:

#include <wchar.h>

....

wchar_t wc;
wc=L'à';
printf("%u \n",(unsigned)wc);

【讨论】:

此答案的编写方式不会向不熟悉字符集并通过字节表示的人解释。 “第 7 位被设置在每一个中”与“à 的代码点存储为 0x3C 0xA0”相矛盾,因为第 7 位未在 0x3C 中设置。 @EricPostpischil 谢谢,已修复。

以上是关于C中的无符号字符未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

C - 结构中的无符号字符

c_cpp 使用C ++中的无符号字符的示例

如何在c中的无符号字符中移动字节

如何将字节数据从套接字写入 C 中的无符号字符向量? [关闭]

C# 中的无符号字符使用哪种数据类型?

如何在c中读取由空格分隔的无符号字符