GargantuChet 已经正确解释了为什么你会得到'a'。
更一般地说,还有许多其他问题
1 for (;;)
2 {
3 char ch;
4 if (cin.fail()) break;
5 cin.read((char*)&ch, sizeof(unsigned char));
6 cout << hex << (unsigned int)(unsigned char)ch < <endl;
7 cin.clear();
8 }
在第 4 行,您会看到是否cin.fail()
已设置,但是对于流,它们将永远不会以失败状态启动 - 您必须尝试做一些事情以使其失败。换句话说,您应该read()
先看看cin.fail()
. 通常,您还应该使用gcount()
来检查实际可以读取多少字节(例如,尽管要求说 4,但您可能只会得到 2,这不会被视为失败),但在这里您只请求 1 个字符,所以它可以更简单。
稍微清理一下,但保持相同的基本方法:
1 for (char ch; cin.read(&ch, sizeof ch); )
2 cout << hex << (unsigned)(unsigned char)ch < <endl;
这是有效的,因为read()
返回对 的引用cin
,并且评估 的“真值”cin
是询问到目前为止它执行的输入是否没有错误的简写(更严格地说,至少从最后一次开始,clear()
如果你正在使用它)。
尽管如此,std::istream
- 其中std::cin
是一个实例 - 还具有设计用于获取字符的功能,允许将循环简化为:
for (char ch; std::cin.get(ch); )
...
在旁边
请记住,for( ; ; )
控制语句包含三个部分:
- 左侧的初始化代码也可以创建新变量
- 测试:这发生在循环语句的第一次和每次后续执行之前
- 仅在每次执行语句之后和重复测试之前执行的代码。
正因为如此,像这样的测试std::cin.get(ch)
被调用并评估成功作为每次迭代的条件。上面列出的最后一个解决方案等效于:
{
char ch;
while (std::cin.get(ch))
...
}