问题描述
我有一个奇怪的输入文件,里面有各种控制字符,比如空值。我想从这个 Windows-1252 编码的文本文件中删除所有控制字符,但如果你这样做:
std::string test="tést";
for (int i=0;i<test.length();i++)
{
if (test[i]<32) test[i]=32; // change all control characters into spaces
}
它也会将 é 变成空格。
因此,如果您有这样的字符串,以 Windows-1252 编码:
std::string test="tést";
十六进制值为:
t é s t
74 E9 73 74
见https://en.wikipedia.org/wiki/ASCII和https://en.wikipedia.org/wiki/Windows-1252
test[0] 将等于十进制 116 (=0x74),但显然对于 é/0xE9,test[1] 不等于十进制值 233。
那么你如何正确识别那个é?
解决方法
改变
if (test[i]<32)
到
if (test[i] >= 0 && test[i] < 32)
字符通常是有符号类型,而 0xE9
是八位整数中的负值。
32
是有符号整数,将 char
与有符号整数进行比较由编译器执行为有符号:E9 (-23)
使用 32
的无符号文字,即 32u
使比较对无符号值执行:E9 (233)
替换:
if (test[i]<32) test[i]=32;
作者:
if (test[i]<32u) test[i]=32u;
你应该得到预期的结果。
在这里测试: https://onlinegdb.com/BJ8tj0kbd
注意:您可以检查 char
是否使用以下代码签名:
#include <limits>
...
std::cout << std::numeric_limits<char>::is_signed << std::endl;