为什么这个C ++代码会在每一行之后打印出来?

时间:2011-07-01 03:19:43

标签: c++ cin

#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阅读未格式化的输入。

4 个答案:

答案 0 :(得分:3)

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

您可能没有想到的是按下Enter键也会发送一个字符,通过拨打cin.read来读取该字符。

a是该字符的十六进制值。因此,如果您输入hello并按Enter,则会从cout语句中产生以下内容:

68
65
6c
6c
6f
a

如果您停止以十六进制显示值,您会注意到每次输入后都会打印10

答案 1 :(得分:2)

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

如果你不想看到那个字符,只需将输出行包装在一个if语句中,该语句检查该字符,并且在看到它时不打扰任何输出:

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

答案 2 :(得分:1)

我甚至不知道你要用这​​个来完成什么。不要使用cin.read来读取单个字符。这个循环看起来应该更像这样:

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

至于为什么要打印一些东西,你确定它不是你实际输入的角色吗?

答案 3 :(得分:1)

GargantuChet已经正确地解释了为什么你会得到'a's。

更一般地说,还有许多其他问题

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