如何尝试读取为int,然后如果它失败读取为字符串?

时间:2013-07-06 01:43:30

标签: c++ cin

我正在尝试重复读取整数,以及非整数的标记,以读取和处理它们作为字符串。我认为以下内容可行:

string s;
int x;

while(1) {
    if (cin >> x)                                     // try reading as int
        cout << "read int: " << x << endl;
    else {                                            // try reading as string
        cin.clear();

        if (cin >> s) 
            cout << "read string: " << s << endl;
        else
            break;                                    // eof
    }
}

但是,输入(结尾处有换行符)

1 2 a

它提供输出

read int: 1
read int: 2

似乎清除流的状态与以前不完全相同,实际上cin >> s失败了。为什么会这样,我怎样才能实现我想要的行为?

为了澄清,我无法将字符串解析为int,因为我还没有“学会”它。

2 个答案:

答案 0 :(得分:5)

clear不会回放流;它只有clears the error flags,顾名思义。要解决您的问题,请将输入作为字符串读取,然后try to parse it as an int。该链接比我更好地解释了string-int转换的细节。

答案 1 :(得分:2)

为什么不将其作为字符串读取,然后尝试转换,因此如果转换失败,您可以将其视为字符串。

在C ++ 11中有std::stoi。如果无法找到转换,则会抛出异常。

另一种方法是将其作为字符串读取,然后使用字符串流进行解析。

如果你不能使用现有的字符串解析方法,为什么不编写自己的?

// Returns false if not an int, otherwise true and outint will hold the correct value.
bool strtoint(const std::string str, int *outint) {
    int val = 0;
    for (int x = str.length() - 1; x >= 0; x--) {
        if (!(str[x] <= '9' && str[x] >= '0') || !(str[x] == '-')) {
            return false;
        } else if (str[x] == '-') {
            val *= -1;
        } else {
            val += (int)((str[x] - '0') * pow(10, (str.length() - 1) - x));
        }
    }

    *outint = val;
    return true;
}

或者类似的东西,我不确定逻辑是否完全正确,但我认为它是在正确的轨道上。