Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[c++] Zczytywanie wyrazów z linii

despotka 27 Mar 2011 20:51 1792 3
  • #1 27 Mar 2011 20:51
    despotka
    Poziom 8  

    Elo.

    Mam takie zadanie, że program dostaje na wejście w jednej linijce wyrazy (oddzielone spacjami), problem jest tylko taki, że nie jest znana ich ilośc. Co muszę zrobić, aby program wczytywał kolejne wyrazy do strignów, ale tylko do momentu aż się skończy linijka?

    Probowałem zrobić to tak:

    Code:
    string s;
    
    vector <string> vec;

    do
    {
       cin >> s;
       vec.push_back(s);
    }
    while(cin);


    Niestety to nie działa, bo nawet gdy program już przejedzie cała linijkię, to nadal czeka na kolejne dane do wczytania?
    Jak temu zaradzić?

    0 3
  • Pomocny post
    #2 27 Mar 2011 21:22
    Dariusz Bismor
    Poziom 17  

    Zła wiadomość: nie da się tego zrobić operacjami wysokiego poziomu (czyli operatorem wyciągania ze strumienia ">>").
    Dobra wiadomość: nie jest to takie trudne! Musisz wczytać całą linię na raz, za pomocą funkcji getline() i wpakować ją do strnigu. Potem ten string trzeba "poszatkować" na pojedyncze wyrazy. Procedurę "szatkującą" nazywa się zwykle tokenizerem. Można to zrobić na wiele sposobów, ja polecam definiować obiekt typu istringstream z zawartością taką, jak ten długi string, i dalej już normalnie z niego wczytywać - jak z cin.

    HTH,
    Dariusz
    PS Wszędzie, gdzie pisałem "string" miałem na myśli obiekt typu "string" zadeklarowany w <string>

    0
  • #3 28 Mar 2011 15:48
    despotka
    Poziom 8  

    Hej, to znów ja.

    Zczytywanie linijki i dzielenie przez istringstream działa bardzo dobrze, jednak kolejny problem pojawia się gdy przed tym chcę jeszcze wczytać ilość linijek które dostanie program.
    Gdy ilośc linijek narzucę z góry, wtedy ładnie zczytuje każdą po kolei, ale gdy przed rozpoczęciem pętli wczytam jakąś wartość do licznika (próbowałem cin i scanf), wtedy program wyrzuca bład. Sprawdzałem debuggerem i wydaje mi się że po wczytaniu wartości do licznika program po prostu pomija albo istrukcję wczytania linijki, albo inicjalizację obiektu istringstream.

    Jak można to naprawić i przed zczytywaniem tekstu wczytać jeszcze ilość linijek które dostanie program?


    Wygląda to teraz tak:

    Code:
    int cnt;
    
    string s, temp;
    vector <string> v;

    cin >> cnt; // (lub scanf, też nie działa)

    while(cnt--)
    {
       getline(cin,s);
       istringstream is (s,istringstream::in);

       while(is.good())
       {
          is >> temp;
          v.push_back(temp);
       }


       s.clear();
       temp.clear();
       is.clear();
    }

    0
  • Pomocny post
    #4 28 Mar 2011 16:03
    Dariusz Bismor
    Poziom 17  

    Nie mam czasu tego sprawdzić, ale chyba chodzi o to, że w strumieniu pozostaje niewyciągnięty znak końca linii. Dodanie cin.ignore() załatwi sprawę:

    Code:
    cin >> cnt; // (lub scanf, też nie działa) 
    
    cin.ignore(numeric_limits<streamsize>::max(), '\n' );

    Instrukcja wyciąga ze strumienia i ignoruje tyle znaków, ile podaje pierwszy argument, ale nie dalej, niż do wystąpienia drugiego argumentu. Zamiast numeric_limits<streamsize>::max() można wpisać jakąś dużą liczbę, np. 1000.

    Widzę, że potrzebujesz jakiejś przyzwoitej książki o bibliotece IOStreams.

    HTH,
    Dariusz

    0