为什么这个C++代码在每行后面都打印一个

why does this C++ code print a after every line?

本文关键字:打印 一个 C++ 代码 为什么      更新时间:2023-10-16
#include <iostream>
using namespace std;

int main() {
  for (;;) {
    char ch ;
    if (cin.fail()) break;
    cin.read((char*)&ch, sizeof(unsigned char));
    cout<<hex<<(unsigned int)(unsigned char)ch<<endl;
    cin.clear();
  }   
}

为什么这个代码总是在每行之后打印a?我只是使用任何char作为标准输入添加:我正在尝试用read读取未格式化的输入。

此代码一次读取一个字符,并以十六进制形式写出该字符的值。

您可能没有想到的是,按Enter键还会发送一个字符,该字符由您对cin.read的调用读取。

a是该字符的十六进制值。因此,如果您键入hello并按Enter,则cout语句将产生以下结果:

68
65
6c
6c
6f
a

如果您停止以十六进制显示值,您会注意到它在每个条目后都会打印10

您看到的a只是输入行末尾的'n'字符的十六进制值。

如果您不想看到该字符,只需将输出行包装在if语句中,该语句检查该字符,并且在看到该字符时不需要进行任何输出:

if (ch != 'n') {
    cout<<hex<<(unsigned int)(unsigned char)ch<<endl;
}

我甚至不知道你想用它实现什么。不要使用cin.read来读取单个字符。这个循环应该更像这样:

char ch;
while (std::cin.get(ch)) {
    std::cout << std::hex << static_cast<unsigned>(ch) << std::endl;
}

至于为什么它会打印一些东西,你确定这不是你实际输入的字符吗?

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))
        ...
}