Wczytywanie danych do vectora z pomocą iteratorów

0

Witam wszystkich!

Mam pewien problem z wczytywaniem danych do vectora przy użyciu iteratorów. Otóż chodzi o to, że mam plik z danymi, które są w następującym formacie: w pierwszej linijce znajduje się liczba, która określa ilość zestawów danych, które program ma przetworzyć. Następna linijka określa długość konkretnego zestawu danych, a jeszcze kolejna zawiera już same dane. Tak więc plik zawierający dwa testy, odpowiednio o "długości danych" 3 i 5 ma następujący wygląd:

2
3
12 42 623 //dane
5
123 52 52 23 626 //dane

Każda linia danych kończy się spacją i znakiem nowej linii!

Wczytywanie liczb do programu chcę zrealizować następującym kodem (wiem, że da się to zrobić inaczej ale ja uparłem się właśnie na ten sposób w celach poznawania STL'a):

#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>

std::string getline(std::istream& input_stream) {
  std::string line;
  getline(input_stream, line);
  return line;
}

int main(int argc, char* argv[]) {
  std::vector<int> data_to_sort;
  int number_of_tests = std::stoi(getline(std::cin));
  std::cout << "Number of test: " << number_of_tests << std::endl;

  for(unsigned int i = 0; i < number_of_tests; ++i) {
    int data_size = std::stoi(getline(std::cin));
    std::cout << "Data size: " << data_size << std::endl;

    data_to_sort.reserve(data_size);
    std::copy_n(std::istream_iterator<int>(std::cin), data_size, std::inserter(data_to_sort, data_to_sort.begin()));

    for(int number : data_to_sort) {
      std::cout << number << " ";
    }
    std::cout << std::endl;

    //tutaj obrobka danych w vectorze
  }
}

Problem jest następujący - po wczytaniu pierwszego zestawu danych, czyli na początku drugiego obiegu pętli, funkcja getline zwraca pusty znak, który nie jest przetwarzany poprawnie przez std::stoi i przez to wylatuje wyjątek. Niestety nie wiem co jest nie tak - próbowałem googlować mój problem ale z marnym skutkiem, gdyż nie wiem nawet jak nazwać to, co konkretnie się dzieje. Kiedy użyje mojego getline'a dwa razy pod rząd to za drugim razem program poprawnie łapie kolejną linię testowego wejścia. Przypuszczam, że ma to jakiś związek z std::inserter, którego używam w moim rozwiązaniu. Zamieszczam wyjście mojego programu:

./sort < testInput.txt 
Number of test: 84
Data size: 5
341 188 383 661 682 
libc++abi.dylib: terminating with uncaught exception of type std::invalid_argument: stoi: no conversion
Abort trap: 6

1

Mieszasz getline z std::cin. cin dla liczb nie wyjmuje tylko je z wejścia standardowego. Prześledźmy teraz co się dzieje dla Twojego wejścia:
zakładam, że wejście to:

2
3
12 42 623
5
123 52 52 23 626

Pozycję do której wczytano oznaczę ·
Początek:

·2
3
12 42 623
5
123 52 52 23 626

int number_of_tests = std::stoi(getline(std::cin));

2
·3
12 42 623
5
123 52 52 23 626

int data_size = std::stoi(getline(std::cin));

2
3
·12 42 623
5
123 52 52 23 626

std::copy_n(std::istream_iterator<int>(std::cin), data_size, std::inserter(data_to_sort, data_to_sort.begin()));
data_size to 3, więc po każdej iteracji:

s
3
12· 42 623
5
123 52 52 23 626
s
3
12 42· 623
5
123 52 52 23 626
s
3
12 42 623·
5
123 52 52 23 626

Jak widzisz, następna wczytana linia z getline wczyta "\n".
Rozwiązanie: zignoruj następną linię, lub wszędzie po prostu wczytuj za pomocą std::cin >> foo, co we wszystkich spojopodonych zadaniach jest rozwiązaniem dużo wygodniejszym.

Jeśli koniecznie chcesz ignorować:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
1

std::cin.ignore() po cout << endl;
I chyba co obieg fora powinienneś czyścić wektor?

1 użytkowników online, w tym zalogowanych: 0, gości: 1