每当我做类似于以下情况的事情时,我都会收到多字符警告。
char str[] = "León";
if(str[2] == 'ó') printf(true);
我该如何解决这个问题?
答案 0 :(得分:5)
除非平台上的编码使'ó'
适合char
,否则'ó'
是一个多字符常量。从您获得的信息来看,它似乎是您平台上的后者。多字符常量的值是实现定义。换句话说,数值的选择取决于实现,有一些约束(例如,它必须在您平台的char
范围之外)。
令人遗憾的是,在您编写char str[] = "León";
的情况下,第三个元素将转换为char
,使用缩小转化,或者分解为多个char
1}}和连接到char[]
数组。因此,将其与'ó'
进行比较的尝试将是徒劳的。
答案 1 :(得分:1)
您需要使用wchar_t
类型或unicode库。 wchar_t
因为有许多问题和容易出错的bug而臭名昭着,但它是C ++编译器可用的最佳原始类型。
您需要使用支持wchar_t
的所有内容的变体,例如std::wcout
或wprintf
。
编辑:wchar_t
已被char16_t
和char32_t
取代。 Unicode标准4.0建议在代码必须在平台之间移植时使用它们,因为wchar_t
的大小因平台而异(如int
所做的那样)。
我建议找一个好的unicode库来处理由多个代码点组成的多个字符之间的比较!
另一种选择是完全坚持原生char
类型,通常将其解释为某些特定于语言环境的ASCII。
答案 2 :(得分:1)
如果要使用扩展的ASCII字符,请使用它们的八进制值。
我正在使用表http://www.asciitable.com/,我猜你需要的值是162(十进制)= 242.所以使用str[] = "Le\242n"
;
并在比较中使用相同的内容。
答案 3 :(得分:0)
ASCII是一个7位字符编码,用于对字符0
... 127
进行编号。 ASCII兼容编码保留了这些字节的含义。编码为c < 0
或c > 127
的任何字符都不能是ASCII字符。这些有时可以被各种令人困惑的名称调用,例如&#34;扩展的ASCII&#34;或者一样。
在Unicode中,ASCII字符仍然是Unicode代码点范围的字符0 ... 127。
问题不在于ó
是一个扩展字符,而是您的源文件实际上是 UTF-8 ,因此ó
被编码为 2个字节。 C中的char
代表通常在其他地方称为 byte 的东西。
C还支持宽字符字符串,其中每个字符都是UTF-16,UCS-2,UTF-32或其他一些代码点。您的ó
(最有可能)会是一个wchar_t
。
不幸的是,你在这里打开了一堆蠕虫,因为符号ó
也可以用两种不同的方式用Unicode编写:它可以写成一个代码点ó
或者字母o
后面加上组合的重音:́
;两者都有相同的语义信息,但它们由不同的字节组成。即使转换为wchar_t
字符串,这些仍然会有不同的序列。 C标准库根本不处理Unicode,除了在C11中,其中在UTF-8中明确支持字符文字。 C标准仍然没有提供将UTF-8编码的文本数据转换为wchar_t
的可移植方式;它也不能进行标准化,例如ó
到o ́
,反之亦然。
答案 4 :(得分:0)
您可以执行类似
的操作if (sizeof("ó") > 2) ...
如果只有一个char
,则字符串的长度为2
,一个用于字符,另一个用于终止0
。否则,如果它不合适,编译器将分配更长的序列。
答案 5 :(得分:0)
当您将源文件提供给编译器时,您必须告诉您使用源编辑器使用的字符编码(source charset)。我猜它是UTF-8,它编码为0xC3 0xB3。这似乎是正确的。
但是'ó'会变成一个整数,其值超出char
范围(请参阅<limits.h>
)。因此,==
之间会发出警告。