switch语句匹配非ASCII字符

7

我在源代码中使用了带有音标的字符,并尝试用Unicode等效字符替换它们。如果我使用实际的非ASCII字符,程序编译并正常工作,但我担心这可能会影响可移植性。当我尝试使用Unicode等效字符时,我会得到“警告:情况标签值超过类型的最大值”或“警告:字符常量对其类型太长”,并且在运行程序时该情况永远不匹配。

for(int i = 0; i < ent->d_namlen; i++)
{
    switch(ent->d_name[i])
    {
        case 'á' : //0x00E1
        ...
    }
 }

参数ent 是一个从调用函数传递过来的 struct dirent *

case 'á' : 的位置,我尝试了 case '0x00E1' :, case L 'u00E1 :, case \U000000E9 :case '\u00E1' :。但是如果没有使用单引号,则无法编译(例如,会说在此范围内未声明 \u00E1)。


1
你正在切换的变量类型是什么? - David
@Dave dirent.d_namechar[] - obataku
你的Unicode字符被编码为多字节值(00E1是两个字节)。你可能正在切换该字符的第一个字节...即0。你可以尝试添加一个针对0的case,然后检查d_name [i + 1]是否为E1。或者,编写一些代码来转储d_name中的数字值,以便您可以逐字节地查看编码,并使用它来指导您检测该字符。 - Tony Delroy
显示d_name中字符的值,以查看您应该寻找什么。为此,请使用printf(“%d”,d_name [whatever])std :: cout <<(int)d_name [whatever] - Pete Becker
@veer 你是指这里描述的多字节字符集吗?(http://www.codeproject.com/Articles/2995/The-Complete-Guide-to-C-Strings-Part-I-Win32-Chara) - Celeritas
显示剩余13条评论
2个回答

2

á 是一个非ASCII字符,在您的源代码、struct dirent 中,或者两者都存在时,会被表示为多个字节。

如果您打开-Wmultichar,可能会收到警告。

warning: multi-character character constant

表明字符常量'á'由多个字节组成,这种情况下它可能是UTF-8编码,但需要检查(例如使用file命令)。您还需要找出dirent条目的编码方式。
为了匹配字符串中的非ASCII字符,您需要:
- 确保字符串和字符以相同的编码方式表示,并且要么 - 使用固定长度编码(即UCS-4)和足够宽的类型来存储每个代码点(例如int),或者 - 使用可重启的可变长度编码(即UTF-8)并使用子字符串匹配。
请参考http://en.cppreference.com/w/cpp/locale/codecvt_utf8了解如何进行转换。

0

我认为将switch表达式转换为无符号类型就可以解决问题。

switch((unsigned char)ent->d_name[i])
{
...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接