C++如何检测输入流中的非ASCII字符 现有代码返回值异常如何解决
问题原因
- 编码不匹配是核心原因:你单独写
unsigned char c = '‰'得到137,只是因为你的源码保存时采用了Windows-1252这类单字节扩展ASCII编码,编译器直接把该字符对应的单字节值赋给了变量。但运行时终端输入默认采用UTF-8编码,‰的UTF-8编码是三字节序列0xE2 0x80 0xB0,读入std::string后遍历得到的单个字节自然不会是137,你看到的37实际是百分号%的ASCII码,大概率是输入过程中编码转换出错导致的乱码。 - C++标准中多字节字符常量的数值是实现定义的,你的写法本身不具备可移植性,不同编译器、不同源码编码下得到的结果可能完全不同。
- 标准输入流默认会跟随系统locale做编码转换,也可能导致你读入的字节和实际输入的原始字节不一致。
正确实现方案
如果你只是要过滤所有非可打印ASCII字符(即要求所有字符都是ASCII 32~127的范围),可以直接关闭输入流的locale转换,按原始字节读取后逐个判断即可,参考实现代码如下:
#include <string> #include <iostream> #include <locale> int main() { // 关闭输入流的编码转换,按原始字节读取 std::cin.imbue(std::locale::classic()); std::string password; std::cin >> password; for (unsigned char c : password) { if (c < 32 || c > 127) { std::cout << " ! Invalid password inserted !\n"; return 0; } } std::cout << "Valid password\n"; return 0; }
如果需要明确识别特定的扩展ASCII字符(比如值为137的‰),需要统一设置输入流、终端、源码的编码为同一种单字节编码,避免多字节编码的拆分问题。
内容的提问来源于stack exchange,提问作者Danny G
相关产品推荐
相关产品推荐

