2016-04-01 31 views
-1

yılında std :: istream_iterator Aşağıdaki metin dosyası vardır:Yeniden std :: stringstream ve döngü

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 

aşağıdaki programla okuyabilirsiniz:

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

Ben oluşturmak istiyorum std::stringstream ve std::istream_iterator döngüden yalnızca bir kez. Döngü aşağıdaki programda her yürütüldüğünde yineleyiciyi doğru konuma nasıl ayarlayabilirim? İkinci yaklaşım esere iki öğe yapabilmek için

#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 ve std :: istream_iterator öğesini yalnızca döngü dışında bir kez oluşturmak istiyorum." _ Neden aslında? XY problemi gibi görünüyor. –

cevap

1

ele alınması gerekir:

  1. std::stringstreamss tekrar kullanılabilir, böylece eof bayrak silinir olmalıdır. Bunun için ss.clear() kullanabiliriz.
  2. Sonra, ss'a yeni veriler eklendikten sonra std::istream_iterator, std::stringstream'dan yeni girişi görebilmesi için sıfırlanmalıdır. Buradaki anahtar, oluşturulduğu anda yineleyicinin sağlayacağı ilk değeri okuduğunun farkına varmaktır.

Öyleyse programı haline gelir:

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

Visual Studio 2015 yılında yaptım şu:

  • Ben girişlerinin çok ve orada ile programın iki sürümü koştu fark edilebilir bir fark değildir. ifadesi start = ss; her durumda kurucu çağırmak gibi görünüyor, çünkü çoğu zaman iki durumda da
  • yineleyici inşa harcanmaktadır.