2016-04-01 15 views
-1

でistream_iterator私は、次のテキストファイルがあります。リユースのstd ::にstringstreamとstd ::ループ

0 0 0 0 0 1 0 0 2 3 4 2 1 2 1 
0 0 0 0 2 7 5 4 5 7 5 4 3 
3 2 4 6 2 7 2 7 5 4 5 7 5 4 3 
3 2 4 6 2 7 2 7 5 4 5 4 3 
0 0 0 0 0 1 0 2 3 4 2 1 2 1 
0 0 0 0 0 1 0 0 2 3 4 2 1 2 1 
0 0 0 0 2 1 2 1 
3 2 4 6 2 7 2 7 5 4 5 7 5 4 3 
3 2 4 6 2 0 2 3 4 2 1 2 1 
0 0 0 0 0 1 0 0 2 3 4 2 1 2 1 
3 2 4 6 2 7 2 7 5 4 5 7 5 4 3 

を、私は次のプログラムでそれを読むことができます:

#include <iostream> 
#include <iterator> 
#include <fstream> 
#include <vector> 
#include <string> 
#include <sstream> 

int main() 
{ 
    std::ifstream is("numbers.txt"); 
    std::string line; 
    std::vector<std::vector<int>> numbers{}; 
    while (std::getline(is,line)) { 
     std::stringstream ss{line}; 
     std::istream_iterator<int> start{ss},end; 
     numbers.emplace_back(start,end); 
     std::cout << "Read " << numbers.back().size() << " numbers in row\n"; 
    } 
    std::cout << "Read " << numbers.size() << " rows\n"; 

    std::cout << "numbers read in:\n"; 
    for (auto row : numbers) { 
     for (auto number : row) { 
      std::cout << number << " "; 
     } 
     std::cout << "\n"; 
    } 
    std::cout << std::endl; 
} 

私が作成したいと思いますstd::stringstreamstd::istream_iteratorは、ループの外側に1度だけあります。ループが次のプログラムで実行されるたびに、イテレータを正しい位置に調整するにはどうすればよいですか?

#include <iostream> 
#include <iterator> 
#include <fstream> 
#include <vector> 
#include <string> 
#include <sstream> 

int main() 
{ 
    std::ifstream is("numbers.txt"); 
    std::string line; 
    std::vector<std::vector<int>> numbers{}; 
    std::stringstream ss{line}; 
    std::istream_iterator<int> start{ss},end; 
    while (std::getline(is,line)) { 
     ss << line; 
     //start = ss.beg; 
     numbers.emplace_back(start,end); 
     std::cout << "Read " << numbers.back().size() << " numbers in row\n"; 
    } 
    std::cout << "Read " << numbers.size() << " rows\n"; 

    std::cout << "numbers read in:\n"; 
    for (auto row : numbers) { 
     for (auto number : row) { 
      std::cout << number << " "; 
     } 
     std::cout << "\n"; 
    } 
    std::cout << std::endl; 
} 
+0

_ "私はstd :: stringstreamとstd :: istream_iteratorをループの外に1回だけ作成したいと思っています。" XY問題のように聞こえる。 –

答えて

1

取り組まなければならない第二のアプローチの仕事に二つのアイテムを作るために:

  1. std::stringstreamssは、それが再び使用できるようにクリアeof旗を持っている必要があります。このためには、ss.clear()を使用できます。
  2. 新しいデータがssに追加されたら、std::istream_iteratorをリセットして、std::stringstreamからの新しい入力を確認する必要があります。ここでの鍵は、イテレータが構築されるとすぐに、それが提供する最初の値を読み込むことを認識することです。

それではプログラムは次のようになります。Visual Studioで

#include <iostream> 
#include <iterator> 
#include <fstream> 
#include <vector> 
#include <string> 
#include <sstream> 

int main() 
{ 
    std::ifstream is("numbers.txt"); 
    std::string line; 
    std::vector<std::vector<int>> numbers{}; 
    std::stringstream ss{line}; 
    std::istream_iterator<int> start{ss},end; 
    while (std::getline(is,line)) { 
     ss.clear(); // clear eof flag 
     ss << line; // ok to add data 
     start = ss; // reset the iterator so that it will see the new data 
     numbers.emplace_back(start,end); 
     std::cout << "Read " << numbers.back().size() << " numbers in row\n"; 
    } 
    std::cout << "Read " << numbers.size() << " rows\n"; 

    std::cout << "numbers read in:\n"; 
    for (auto row : numbers) { 
     for (auto number : row) { 
      std::cout << number << " "; 
     } 
     std::cout << "\n"; 
    } 
    std::cout << std::endl; 
} 

2015私は次のようでした:

  • 私はエントリの多くが付いているプログラムの2つのバージョンを実行し、そこ 顕著な違いはありません。どちらの場合も

  • 声明start = ss;はどのような場合に コンストラクタを呼び出しているように見えるので、ほとんどの時間は、イテレータ を構築費やされています。

関連する問題