0

我只是在搞乱一些流和迭代器,一切都很好,直到我尝试了下面的代码。我期望输出是输入文件中逐行打印的所有单词。我知道我可以在 ifstream 上使用 >> 运算符,但我只是编写这段代码来更好地掌握流和迭代器。我得到的当前输出是第一行的所有单词都打印在他们自己的行上。

#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;
}
4

4 回答 4

3

重置您的错误标志std::istringstream

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

您的调用std::copy耗尽了底层缓冲区,并且您的std::istringstream对象处于失败状态(eofbit 设置)。

于 2013-08-30T12:02:30.877 回答
1

您应该iss在循环中定义。每次循环都需要一个新的、干净的:

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

否则,iss保留以前使用的状态,这是您不想要的。

于 2013-08-30T12:17:21.103 回答
0

例如,如果您阅读此参考资料,std::istream_iterator您将看到它用于operator>>获取输入,并且operator>>仅读取以空格分隔的条目。这就是为什么您将每个单词放在不同的行上。

而且您将无法多次读取输入字符串流,因为一旦完成,它就会设置 EOF 标志。要么清除标志,要么在循环内声明字符串流对象。

于 2013-08-30T12:02:46.977 回答
0
   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
   }
于 2013-08-30T12:05:00.150 回答