2013-08-30 75 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保留狀態,從它以前使用的,這 你不想要的。