简体   繁体   English

C ++流和迭代器:为什么只打印一次?

[英]C++ streams and iterators: Why does this only print once?

I was just messing around with some streams and iterators and all was fine until I tried the code below. 我只是在弄乱一些流和迭代器,在我尝试下面的代码之前,一切都很好。 I am expecting the output to be all the words from the input file printed line by line. 我期望输出是输入文件中逐行打印的所有单词。 I know I could just use the >> operator on the ifstream but I was just writing this code to get a better grasp of streams and iterators. 我知道我可以在ifstream上使用>>运算符,但是我只是在编写此代码以更好地了解流和迭代器。 The current output that I'm getting is all the words of line one printed on their own line. 我得到的当前输出是第一行的所有单词都打印在自己的行上。

#include <iostream>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <iterator>

int main (int argc, char* argv[]) {
   if (argc < 3) {
      std::cerr << "Usage: " << argv[0] << " INPUT_FILE OUTPUT_FILE" << std::endl;
   }
   std::string line;
   std::istringstream iss;
   std::ifstream ifs;

   ifs.open(argv[1]);

   while ( getline(ifs, line) ) {
      iss.str(line);
      std::cout << iss.str(); //debug
      std::copy(std::istream_iterator<std::string>(iss),
            std::istream_iterator<std::string>(),
            std::ostream_iterator<std::string>(std::cout, "\n"));
   }

   ifs.close();
   return 0;
}

Reset the error flags for your std::istringstream : 重置您的std::istringstream的错误标志:

while ( getline(ifs, line) ) {
      iss.clear();
      iss.str(line);
      ...
}

Your call to std::copy exhausts the underlying buffer and your std::istringstream object is in a fail state (eofbit set). 您对std::copy调用耗尽了底层缓冲区,并且您的std::istringstream对象处于失败状态(设置了eofbit)。

You should define iss in the loop. 您应该在循环中定义iss You need a new, clean one each time through the loop: 循环中每次都需要一个新的干净的:

while ( std::getline( ifs, line ) ) {
    std::istringstream iss( line );
    //  ...
}

Otherwise, iss retains state from it's previous uses, which you don't want. 否则, iss保留您以前不希望使用的状态。

If you read eg this reference of std::istream_iterator you will see that it uses operator>> to get the input, and operator>> reads only white-space delimited entries. 如果您阅读例如std::istream_iterator此引用,您将看到它使用operator>>来获取输入,而operator>>仅读取以空格分隔的条目。 That's why you get each word on separate lines. 这就是为什么每个单词都放在单独的行中的原因。

And you won't be able to read the input string stream more than once because once it's done it's EOF flag is set. 而且您将不能多次读取输入字符串流,因为一旦完成,它的EOF标志就会被设置。 Either clear the flags, or declare the string stream object inside the loop. 清除标志,或在循环内部声明字符串流对象。

   while ( getline(ifs, line) ) {
      iss.str(line);
      std::cout << iss.str(); //debug
      std::copy(std::istream_iterator<std::string>(iss),
            std::istream_iterator<std::string>(),
            std::ostream_iterator<std::string>(std::cout, "\n"));
            iss.clear(); // celar the iss to reset flags
   }

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

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