【问题标题】:Is is possible to stringstream this way? to convert from string to int?有可能以这种方式串流吗?从字符串转换为int?
【发布时间】:2011-02-20 05:16:41
【问题描述】:

可以这样串流吗? 我正在尝试使用 ifstream 读取并转换它。

string things = "10 11 12 -10";
int i1;
int i2;
int i3;
int i4;
stringstream into;
into << things;
into >> i1;
into >> i2;
into >> i3;
into >> i4;

我希望它是:

i1 = 10
i2 = 11
i3 = 12
i4 = -10

对吗?

同一个stringstream变量可以多次使用吗?

当我尝试时,第一次还可以,但后来一切都只是 0。

【问题讨论】:

  • 这不是你得到的结果吗?
  • 如何编译该代码并亲自查看?
  • 因为在一个实例中产生正确结果的可编译代码总是意味着它是 100% 正确的,尤其是在 C++ 中...

标签: c++ string type-conversion stringstream


【解决方案1】:

那肯定行得通。您甚至可以混合类型,如下所示:

string things = "10 Nawaz 87.87 A";
int i;
std::string s;
float f;
char c;

stringstream into;
into << things;
into >> i >> s >> f >> c; //all are different types!

cout << i <<"  "<< s <<"  "<< f <<"  "<< c;

输出:

10 Nawaz 87.87 A

ideone 演示:http://www.ideone.com/eb0dR

【讨论】:

    【解决方案2】:

    有效吗?我的做法是:

    istringstream into(things);
    into >> i1;
    

    等等。这将产生您发布的输出。

    【讨论】:

      【解决方案3】:

      您发布的内容以及 Jeremiah Willcock 使用 istringstream 的解决方案都有效。但是也可以考虑使用scanf 系列函数(对于几个整数来说并没有太大的区别,但对于更高级的输入,使用 scanf 可能比使用流操纵器更简洁):

      string things = "10 11 12 -10";
      int i1, i2, i3, i4, i5, i6;
      sscanf(things.c_str(), "%d %d %d %d", &i1, &i2, &i3, &i4);
      

      您的示例在此之后只给出 0 的原因是因为 stringstream 缓冲区在您提取 -10 后为空:您必须先向缓冲区插入更多内容,然后才能提取更多内容。您可以多次使用同一个 stringstream 实例,但您要么每次都需要完全使用缓冲区,要么意识到在您插入下一个项目之前缓冲区中还有更多内容:

      string things = "10 11 12 -10", temp;
      int i1, i2, i3, i4;
      stringstream into;
      into << things; //buffer is now "10 11 12 -10"
      into >> i1; //buffer is now " 11 12 -10"
      into >> i2; //" 12 -10"
      into >> i3; //" -10"
      into >> i4; //""
      
      //more code here...
      
      //come back and use the instance again
      into << "more: 1 2 3"; //"more: 1 2 3"
      into >> temp; //temp is "more:"; into's buffer is " 1 2 3"
      into >> i1; //buffer is " 2 3"
      
      //more code here...
      
      //reuse into once again
      into << "4 5 6"; // buffer is now " 2 3 4 5 6"
      into >> i1; //i1 gets the 2 from before, not the 4 just inserted; buffer now " 3 4 5 6"
      into >> i2; //i2==3; buffer is " 4 5 6"
      

      此外,iosstringstream 从中继承)还定义了 ! 运算符和对 void* 的强制转换,以便您可以方便地检查提取是否失败(技术上检查是否 failbitbadbit已设置,我相信failbit 是与eofbit 一起设置的缓冲区,当缓冲区不够时):

      string things = "10 11 12 -10";
      int i1, i2, i3, i4;
      stringstream into;
      into << things;
      into >> i1 >> i2 >> i3 >> i4;
      if (into >> i5) {
          cout << "extraction to i5 succeeded" << endl;
      }
      if (!(into >> i6)) {
          cout << "extraction to i6 failed" << endl;
      }
      

      【讨论】:

      • 使用stringstreamsscanf有很大区别。前者在输出时消耗流中的数据,但后者不消耗。可以反复写sscanf(things.c_str(), "%d %d %d %d", &amp;i1, &amp;i2, &amp;i3, &amp;i4);
      • 感谢您的知识和帮助。我还有一个问题是可以清除字符串流缓冲区吗?
      • 您也可以通过寻求偏移零来重置字符串流。使用 sscanf 是最后的手段,并且仅限于大师。例如,更改 i3 的类型会严重破坏 sscanf 的代码,而 stringstream 只会为 operator>> 选择另一个重载。
      【解决方案4】:

      是的,它会起作用。
      我要做的唯一区别是:

      string things = "10 11 12 -10";
      int i1;
      int i2;
      int i3;
      int i4;
      
      stringstream into(things);    // Initialize in the constructor
      into >> i1 >> i2 >> i3 >> i4; // Chain the inputs.
      

      注意 linestream 就像一个普通的流,当你读完它的结尾时它会用完项目并设置失败状态。

      stringstream into(things)
      int val;
      while(into >> val)                   // loop exits after 4 numbers as into.eof() 
      {                                    // returns true after trying to read the 5 number.
          std::cout << "G(" << val << ")\n";
      }
      

      例如,我喜欢在读取包含 4 个数字的多行时执行以下操作:

      std::string  line;
      while(std::getline(std::cin, line))
      {
          /*
           * This way if a line is formatted incorrectly (only 3 numbers)
           * The error is local to the line and we will pick it up in linestream
           * without affecting the scanning of subsequent lines
           */
          std::stringstream linestream(line);
      
          int i1,i2,i3,i4;
          linestream >> i1 >> i2 >> i3 >> i4;
      }
      

      【讨论】:

        【解决方案5】:

        关于你的第二个问题 同一个stringstream变量可以多次使用吗?,
        重用之前可能需要流的clearseek
        例如,以下代码将解决您的第二个问题:

        int main() {
          string  s = "-1 2";
          stringstream  ss;
          ss << s;
          int i, j;
          ss >> i >> j;
          cout<< i <<' '<< j <<endl;
          ss.clear();
          ss.seekg( 0 );
          i = j = 0;
          ss >> i >> j;
          cout<< i <<' '<< j <<endl;
        }
        

        希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2014-04-24
          • 1970-01-01
          • 2020-08-10
          • 2021-12-30
          • 1970-01-01
          • 1970-01-01
          • 2018-10-26
          • 1970-01-01
          • 2017-09-12
          相关资源
          最近更新 更多