为什么打开字符值不符合大小写0xC2?
Why doesn't switching on a char value reach case 0xC2?
在下面的代码中发现了一个错误,它解析C字符串并应该检测UTF8字符:
char* pTmp = ...;
...
switch (*pTmp)
{
case 'o':
{
... // works fine
break;
}
case 0xC2:
{
... // never gets triggered
break;
}
}
但是,永远不会触发case 0xC2:
。
我的假设是0xC2
被视为int
,因此是 194,大于 127,char
数据类型的最大值。所以-62 != 194
或者这里可能发生一些溢出或整数提升。
编写switch ((unsigned char)*pTmp)
可以解决此问题。
但我想澄清一下这里到底发生了什么以及适用哪些规则。
我也愿意改变标题,只是没有更好的想法。
我在这里添加-Wall
得到这个
warning: case label value exceeds maximum value for type [-Wswitch-outside-range]
14 | case 0xC2:
所以是的,你的推理是正确的。
char
有符号吗?
如果char
具有与signed char
或unsinged char
相同的范围,则它是特定于实现的。 在OP的情况下,char
的范围为[-128 ...127],因此case 0xC2:
永远不匹配。
但我想澄清一下这里到底发生了什么以及应用了哪些规则。
C标准库字符串函数有许多char *
的参数,但这些库函数在内部就像指向unsigned char
数据一样
对于此子句中的所有函数,每个字符都应解释为具有无符号字符类型(因此每个可能的对象表示形式都是有效的并且具有不同的值)。C17DR § 7.24.1 3
为了匹配这一点,OP的代码也应该这样做。 这样做还将允许*upTmp
潜在地匹配0xC2
。
char* pTmp = ...;
unsigned char* upTmp = ( unsigned char*) pTmp;
switch (*upTmp)
case 0xC2:
替代使用十六进制常量0xC2
,使用字符常量:'xC2'
以匹配char
的范围。 @Eric Postpischil。
[迂腐]
"switch ((unsigned char)*pTmp)
解决了问题。" - 它足够接近。
此"修复"适用于 2 的补码char
,以及当定义的实现char
与unsigned char
匹配时。
对于其余但不存在的情况,其中char
是有符号而不是 2 的补码,修复是错误的,因为字符应该通过unsigned char *
访问,否则使用错误的值。
switch (*(unsigned char *)pTmp)
在所有情况下都能正常工作。
- 切换大小写后如何阻止变量重置?
- 无法找到简单的开关大小写枚举错误
- 仿射密码解密,输出大小写不同
- 编写宏函数来更改字符串的大小写?
- 使字母检查不区分大小写
- 如何执行不区分大小写的字符串比较?
- 函数中的切换大小写语句不会切换C++
- CMake 添加不区分大小写的源文件
- 如何在不同的开关大小写语句上使用对象的类成员函数?
- 如何以 if else 或切换大小写格式对自动和编码?
- 有没有一种方法可以忽略Qt c++中的文件名大小写敏感性?
- 标题与标准标题具有相同名称但大小写不同的问题
- Rand()大小写开关在多次迭代后运行到无穷大
- 在这种情况下,如何在基类中设计开关大小写函数
- 提升program_option配置文件的不区分大小写的解析
- 复数大小写中的C++运算符 ->
- 如何提升Perl正则表达式匹配,支持区分大小写/不区分大小写
- 无法在开关大小写中调用函数 - C++
- 对字符串向量进行排序,但不区分大小写
- 开关大小写始终为默认值