stringstream字符串转换为整数

17
下面的C++代码实现了将int转换为string、将string转换为int,然后再次重复这些步骤。但是,在stringstream转换为int时,代码出现了错误:stream1 >> i3;。请问,我错过了什么?
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
 int i1 = 101;
 int i2 = 202;
 int i3 = 0;
 string s1 = "";
 string s2 = "";
 stringstream stream1;

 for (int i=0;i<2;i++)
 {

   //int to string
   stream1.str("");
   cout << "i1 " << i1 << endl;
   stream1 << i1;
   s1 = stream1.str();
   cout << "s1 " << s1 << endl;

   //int to string
   cout << "i2 " << i2 << endl;
   stream1.str("");
   stream1 << i2;
   s2 = stream1.str();
   cout << "s2 " << s2 << endl;

   //string to int
   stream1.str("");
   stream1.str(s2);
   stream1 >> i3;
   //line above causes s1 and s2 to get messed up during 2nd time in for loop
   cout << "i3-- " << i3 << endl;

  }
  return 0;
 }

你应该把 >> 翻转成 <<,你想得到什么输出?我不太明白你的意思。 - Jordan
Abhay,你的codepad链接输出就像我得到的一样。s1和s2不应该为空。如果你注释掉stream1 >> i3这一行,你会发现s1和s2分别是101和202。 - user584583
@user584583:抱歉,是的,那个不应该为空。 - Abhay
4个回答

19

我测试了你的代码并重现了问题。我通过在.str("")之前插入.clear()解决了它。

可以看看这里:如何重用ostringstream?

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
 int i1 = 101;
 int i2 = 202;
 int i3 = 0;
 string s1 = "";
 string s2 = "";
 stringstream stream1;

 for (int i=0;i<2;i++)
 {

   //int to string
   stream1.clear();
   stream1.str("");
   cout << "i1 " << i1 << endl;
   stream1 << i1;
   s1 = stream1.str();
   cout << "s1 " << s1 << endl;

   //int to string
   cout << "i2 " << i2 << endl;
   stream1.clear();
   stream1.str("");
   stream1 << i2;
   s2 = stream1.str();
   cout << "s2 " << s2 << endl;

   //string to int
   stream1.clear();
   stream1.str("");
   stream1.str(s2);
   stream1 >> i3;
   //line above causes s1 and s2 to get messed up during 2nd time in for loop
   cout << "i3-- " << i3 << endl;

  }
  return 0;
 }

16
问题在于在提取整数时,流的EOF标志被设置了(也就是说,stream1.eof()返回true),但您从未清除它。在提取后插入调用stream1.clear()即可解决该问题。

4
在从流中读取i3后,流的eof位被设置。这是因为从流中读取整数会使流一直读取,直到它读取到一个非数字字符或者没有更多字符可读。当遇到后者时,eof位就会被设置。
例如,我可以更改这行代码,
stream1.str(s2);

转换为:

stream1.str(s2 + " ");

当执行stream1 >> i3;时,它会遇到一个非数字字符(' '),停止读取并不设置eof位。

在尝试从中读取之前,您必须通过.clear或其他方法取消设置eof位。


1

我大部分时间都是用C语言,所以我会简单地使用atoi()进行转换:

#include <stdlib.h> // header for atoi()

//stream1 >> i3;  // replace this for the line below
i3 = atoi(stream1.str().c_str());

cout << "i3-- " << i3 << endl;

我正在做的是从sstream中检索一个std :: string,并从中获取一个const char*作为atoi()的参数,该函数将C字符串转换为整数。

这并不完全正确。如果你从stringstream中将数据提取为字符串s3而不是整数i3,那么同样的问题会出现。不管你提取的数据是否进行任何转换,在数据被提取后,stringstream基本上必须使用clear()来重置-- - michel-slm
2
我经常这样做,而不需要调用 clear()。调用 stream1.str() 可以从流中获取信息,而不改变流的状态标志(http://www.cplusplus.com/reference/iostream/stringstream/str/)。 - Max Lybbert
我想我可以把整个应用程序的源代码粘贴过来,这样你们就可以测试它了,但由于代码只对原始源代码进行了2个更改,所以我认为这并不是真正必要的。请放心,这种方法已经经过测试并且有效。 - karlphillip
C++的开发者们不喜欢C语言的回答...这就足以解释为什么会被踩了吗? - karlphillip
https://dev59.com/32ox5IYBdhLWcg3w8IxJ - nvd
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接