[英]Unexpected stringstream behavior
Consider the following code: 考虑以下代码:
#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;
}
Running the above code yields some random output: 运行上面的代码会产生一些随机输出:
12
0
At some other times, the following output is observed: 在其他时间,观察到以下输出:
12
4
I expected the output to be simply: 我希望输出很简单:
12
30
Why did I get the unexpected results? 为什么我得到了意外的结果?
Also, what should be the best way to parse a string s
to int i
without necessary C++11 support? 另外,没有必要的C ++ 11支持,将string s
解析为int i
的最佳方法应该是什么? Should it be int i = atoi(s.c_str())
? 应该是int i = atoi(s.c_str())
吗?
When you extract 12
from the stream, you reach the end of it, which puts it in a bad state. 当从流中提取12
,到达其末尾,这使其处于错误状态。 Any further extractions will fail. 任何进一步的提取将失败。 You need to call ss.clear()
around the time you clear its contents. 您需要在清除其内容时调用ss.clear()
。
If you had checked the success of your extractions, you would have avoided this problem. 如果您检查了提取是否成功,则可以避免此问题。 I generally expect to see any extraction from a stream as some kind of condition. 我通常希望将任何从流中提取的内容视为某种情况。
And yes, using string streams to parse strings as integers is a perfectly reasonable way to do it pre-C++11. 是的,在C ++ 11之前,使用字符串流将字符串解析为整数是一种完全合理的方法。 I would prefer it over using atoi
. 我更喜欢使用atoi
。 For anybody who wants to know the C++11 way, use std::stoi . 对于任何想了解C ++ 11方式的人,请使用std :: stoi 。
For those who're here with something similar to the above but not exactly, I found that when you've got a stream in a scenario where you need to re-use it (like in a while loop), the easiest way to avoid head-aches (in addition to ss.clear
) is to create a new stream each time. 对于那些与上面类似但又不完全相同的人,我发现当您在需要重用流的场景中(例如在while循环中)获得流时,避免这种情况的最简单方法是头痛(除了ss.clear
)是每次创建一个新的流。 For example: 例如:
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();
}
}
So every time the user enters an invalid input, at the start of the while loop, I create a new stringstream object. 因此,每次用户输入无效的输入时,在while循环的开始,我都会创建一个新的stringstream对象。 While researching my function's undefined behavior, I found this question that has a similar example. 虽然研究我的函数的不确定行为,我发现这个问题,有一个类似的例子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.