2013-08-30 80 views
0

我只是搞乱了一些流和迭代器,并且一切都很好,直到我尝试下面的代码。我期待输出是从输入文件逐行打印的所有单词。我知道我可以在ifstream上使用>>操作符,但我只是编写这些代码以更好地掌握流和迭代器。我得到的当前输出是自己行上打印的第一行的所有单词。C++流和迭代器:为什么只打印一次?

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

回答

3

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

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

您对std::copy呼叫耗尽了基础缓冲区和你std::istringstream对象处于失效状态(eofbit集)。

+0

在循环中定义并构造'iss'。 –

+0

@JamesKanze:为什么这会更好? –

+0

因为它可以确保'iss'具有干净的状态。如何清除所有可能的状态并不明显。 –

0

如果您阅读例如this reference of std::istream_iterator你会看到它使用operator>>来获得输入,而operator>>只读取空格分隔的条目。这就是为什么你在单独的行中得到每一个字。

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

+0

有谁知道如何有效地清除_all_的标志? (在这个简化的例子中,这很明显,但总的来说呢?) –

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 
    } 
1

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

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

否则,iss保留状态,从它以前使用的,这 你不想要的。