将char分配给int变量时的奇怪行为

时间:2012-05-23 09:15:48

标签: c++

鉴于此代码:

#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;
}

INPUT 1test

输出 a是1 b是测试 *没有执行getchar *

INPUT 1 测试

输出 a是1 b是测试

INPUT t检验

输出 a是0 b是

INPUT

//跳过第二个cin

输出 a是0 b是

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

3 个答案:

答案 0 :(得分:2)

您可能在第一个角色后点击了Enter。您没有任何代码可以使用该输入,因此您将获得一个空字符串。您的代码不希望两个输入之间有任何分隔符,因此请不要输入任何分隔符。

答案 1 :(得分: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,直到它为止 成功输入。)

第二个是>>运算符仅提取字符 目标必需:>>int将在第一个停止 非数字字符,第一个白色的>>std::string 空间(在两种情况下,在跳过前导空格之后)。这个 意味着在"1test\n"之类的东西之后,仍会有一个 缓冲区中的'\n'。虽然混合通常是一个坏主意 如果他们是正确的,FILE*(如getchar())和iostream 已同步,getchar()会立即阅读此'\n'并返回。

如果您正在阅读面向行的输入,那么最好的解决方案就是使用 getline(),然后将该行放入std::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...

答案 2 :(得分:0)

当您输入char并希望阅读int时,cin信息流将设置为failbit。如果操作失败(设置了以太cin.fail()true),则调用failbit将返回badbit。你可以从那里采取相应的行动。

请注意,cin可以转换为bool进行测试,根据标准,此布尔值与!cin.fail()相同,!cincin.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');

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