繁体   English   中英

意外的字符串流行为

[英]Unexpected stringstream behavior

考虑以下代码:

#include <sstream>
#include <iostream>

using namespace std;

int main()
{
    stringstream ss;

    ss << string("12");
    int h;
    ss >> h;
    cout << h << endl;

    ss.str(string("")); // clear the content of ss

    ss << string("30");
    int m;
    ss >> m;
    cout << m << endl;

    return 0;
}

运行上面的代码会产生一些随机输出:

12
0

在其他时间,观察到以下输出:

12
4

我希望输出很简单:

12 
30

为什么我得到了意外的结果?

另外,没有必要的C ++ 11支持,将string s解析为int i的最佳方法应该是什么? 应该是int i = atoi(s.c_str())吗?

当从流中提取12 ,到达其末尾,这使其处于错误状态。 任何进一步的提取将失败。 您需要在清除其内容时调用ss.clear()

如果您检查了提取是否成功,则可以避免此问题。 我通常希望将任何从流中提取的内容视为某种情况。

是的,在C ++ 11之前,使用字符串流将字符串解析为整数是一种完全合理的方法。 我更喜欢使用atoi 对于任何想了解C ++ 11方式的人,请使用std :: stoi

对于那些与上面类似但又不完全相同的人,我发现当您在需要重用流的场景中(例如在while循环中)获得流时,避免这种情况的最简单方法是头痛(除了ss.clear )是每次创建一个新的流。 例如:

int GetInteger(){
    cout << "Enter an int: " << endl;
    string userInput;
    while (true){
        stringstream ss;
        getline(cin,userInput);
        ss << userInput;
        //Making sure that an int was passed
        int result;
        if (ss >> result){
            //Making sure that there is no extra stuff after
            string extra;
            if (ss >> extra){
                cout << "Unexpected stuff at end of input: " << extra << endl;
            } else{
                return result;
            }
        } else {
            cout << "Number you entered is not an INT. Please enter an integer" << endl;
        }
        cout << "Retry: " << endl;
        // ss.clear();
    }
}

因此,每次用户输入无效的输入时,在while循环的开始,我都会创建一个新的stringstream对象。 虽然研究我的函数的不确定行为,我发现这个问题,有一个类似的例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM