1

鉴于此代码:

#include <cstdio>
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::string;

int main() {
        int a;
        string b;

        cin >> a;
        cin >> b;

        return 0;
}

我尝试用 g++ 编译它并运行它。在将 char 分配给a时,首先cin似乎跳过了以下指令。

即使getchar()在最后两行之间添加两条指令,getchar()似乎也只有第二条被执行。有人可以准确地解释在低级别发生的事情,这似乎导致这些行明显不执行吗?

编辑:

使用此调试代码:

#include <cstdio>
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;

int main() {
        int a;
        string b;

        cin >> a;
        cin >> b;
        cout << "a is "<< a << endl;
        cout << "b is "<< b << endl;
        getchar();

        return 0;
}

输入 1 测试

OUTPUT a is 1 b is test * 没有执行 getchar *

输入 1 测试

输出 a 是 1 b 是测试

输入 测试

输出 a 为 0 b 为

输入 _

// 跳过第二个cin

输出 a 为 0 b 为

注意: getchar()甚至没有执行一次。

4

3 回答 3

2

您可能在第一个字符后按 Enter 键。您没有任何代码可以使用该输入,因此您得到一个空字符串。您的代码不希望在两个输入之间有任何分隔符,因此不要输入任何分隔符。

于 2012-05-23T09:17:58.820 回答
1

从你的输出来看,有两件事。第一个是当你输入时 "ttest"cin >> a;失败。这cin会进入错误状态,直到错误被清除为止。并且只要它处于错误状态,所有其他操作都是无操作的。在尝试使用这些值之前,您确实需要测试输入的结果:

std::cin >> a;
if ( !cin ) {
    std::cerr << "That wasn't an integer" << std::endl;
    std::cin.clear();
}
std::cin >> b;
if ( !cin ) {
    std::cerr << "Where was the string" << std::endl;
    std::cin.clear();
}

a(并且在成功输入之前,不要使用未初始化的变量,例如。)

第二个是>>运算符只提取其目标所需的字符:>>到 aint将在第一个非数字字符处停止,在第>>一个std::string空格处停止(在这两种情况下,在跳过前导空格之后)。这意味着在类似 之后"1test\n",缓冲区中仍然会有 a '\n'。虽然混合 FILE*(like getchar()) 和 iostream 通常是个坏主意,但如果它们正确同步,getchar()'\n'立即读取并返回。

如果您正在阅读面向行的输入,最好的解决方案是使用 getline(),然后将行放入 astd::istringstream中进行解析。所以你的代码最终可能看起来像:

std::string line:
std::getline(std::cin, line);
if ( ! std::cin ) {
    //  Something unexpected went wrong...
    std::cin.clear();
} else {
    std::istringstream l( line );
    l >> a >> b;
    if ( !l ) {
        //  Format error in input...
    } else {
        //  use your data here...
    }
}
std::cin.get();  //  Wait for one more character...
于 2012-05-23T10:19:39.447 回答
0

当您输入 achar并想要读取 aint时,cin流将具有它的failbit集合。如果操作失败(以太或设置) ,调用cin.fail()将返回。您可以从那里采取相应的行动。truefailbitbadbit

请注意,cin可以转换为bool进行测试,根据标准,该布尔值与 相同!cin.fail(),与!cin相同cin.fail()。以下两者是相同的,但有些人可能认为第二个更具可读性。

if(!cin) {
  // cin is in failed state
}

if(cin.fail()) {
  // cin is in failed state
}

一旦cin处于失败状态,任何读取操作cin都将是空操作,直到您将流重置为良好状态。你可以通过调用来做到这一点cin.clear()

但是您还必须意识到,冒犯的角色仍然在流中。也就是说,导致失败状态的非整数字符仍将在流中。你如何处理这取决于你想如何从错误中恢复。一种可能性是打电话

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

这将清除当前行。然后您可以再次提示输入。

于 2012-05-23T09:51:39.027 回答