[英]How to check if a character is an extended ascii character in C?
每次我执行类似于以下情况的操作时,都会收到“多字符”警告。
char str[] = "León";
if(str[2] == 'ó') printf(true);
我该如何解决?
除非平台上的编码使得'ó'
可以适合char
,否则'ó'
是一个多字符常量。 从收到的消息来看,这似乎是平台上的后者。 多字符常量的值由实现定义 。 换句话说,数值的选择要取决于实现,并且要有一些约束(例如,它必须在平台的char
范围之外)。
可悲的是,当您编写char str[] = "León";
,第三个元素将使用缩小转换转换为char
,或者分解为多个char
并连接到char[]
数组。 因此,尝试将其与'ó'
进行比较将是徒劳的。
您将需要使用wchar_t
类型或unicode库。 wchar_t
臭名昭著,因为它有许多陷阱和容易犯的错误,但这是C ++编译器可用的最佳原始类型。
您需要使用所有支持wchar_t
变量,例如std::wcout
或wprintf
。
编辑: wchar_t
已由char16_t
和char32_t
取代。 Unicode标准4.0建议在必须在平台之间移植代码的情况下使用它们,因为wchar_t
的大小取决于平台(就像int
一样)。
我建议找到一个好的Unicode库来处理由多个代码点组成的许多字符之间的比较!
另一个选择是完全遵循本机char
类型,该类型通常被解释为某些特定于语言环境的ASCII。
如果要使用扩展的ASCII字符,请使用其八进制值。
我正在使用表http://www.asciitable.com/ ,我想您需要的值为162(十进制)=242。因此,请使用str[] = "Le\\242n"
;
并在比较中使用相同的内容。
ASCII是7位字符编码,它对字符0
... 127
编号。 ASCII兼容的编码保留了这些字节的含义。 编码为c < 0
或c > 127
任何字符都不能为ASCII字符。 有时可以通过各种令人困惑的名称来调用这些名称,例如“ Extended ASCII”等。
在Unicode中,ASCII字符仍然是Unicode代码点范围的字符0 ... 127。
问题不在于ó
是扩展字符,而是源文件实际上是UTF-8 ,因此ó
编码为2个字节 。 C中的char
代表在其他地方通常称为字节的事物。
C还支持宽字符字符串,其中每个字符都是UTF-16,UCS-2,UTF-32或其他一些代码点。 您的ó
(很可能)是一个wchar_t
。
不幸的是,你在这里打开一罐蠕虫,因为符号ó
也可以写成Unicode的2点独立的方式:它可以写成一个代码点ó
或字母o
其次是组合重音符́
; 两者都有相同的语义信息,但是它们将由不同的字节组成。 即使将其转换为wchar_t
字符串,它们仍然具有不同的顺序。 除了在C11中(在UTF-8中明确支持字符文字)之外,C标准库根本不处理Unicode。 C标准仍然没有提供将UTF-8编码的文本数据转换为wchar_t
可移植方式; 既不它可以做归一化,如ó
到o ́
反之亦然。
你可以做类似的事情
if (sizeof("ó") > 2) ...
如果这只是一个char
则字符串的长度为2
,一个为字符,一个为结尾0
。 否则,如果不合适,编译器将分配更长的序列。
当您将源文件提供给编译器时,必须告诉您在源代码编辑器(源字符集)中使用了哪种字符编码。 我的猜测是UTF-8,将ó编码为0xC3 0xB3。 这似乎是对的。
但是'ó'会成为一个整数,其值超出您的char
范围(请参见<limits.h>
)。 因此,它们之间==
上的警告。
顺便说一句-“扩展ASCII”中有一些含义,但含义不多。 “扩展ASCII”字符集必须在一个字节中对每个代码点进行编码。 因此,UTF-8不是许多“扩展ASCII”字符集之一的编码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.