2012-02-10 24 views
9

Jak wykryć, czy linia jest pusta?Jak wykrywać puste linie podczas czytania z obiektu istream w C++?

mam:

1 
2 
3 
4 

5 

Czytam to z istream r tak:

int n; 
r >> n 

Chcę wiedzieć, kiedy sięgam przestrzeń między 4 i 5. Próbowałem czytania jako char i używając .peek() do wykrycia \ n, ale to wykrywa \ n, który idzie za numerem 1. Tłumaczenie powyższego wejścia to: 1 \ n2 \ n3 \ n4 \ n \ n5 \ n jeśli mam rację ...

Ponieważ zamierzam manipulować intami raczej czytam je jako ints niż używając getline, a następnie konwersja na int ...

+4

¤ Odczytaj każdą linię w 'std :: string' za pomocą' std :: getline'. Sprawdź długość łańcucha. Użyj np. a 'std :: istringstream' do odczytywania pojedynczych elementów z linii wejścia. Pomoże to również w błędnym wprowadzeniu danych. Pozdrawiam & hth., –

+1

Och, właśnie widziałem ostatni akapit, który parafrazując mówi: "Nie chcę korzystać z najłatwiejszego i najrozsądniejszego sposobu". W takim przypadku istnieje zjonizm o bardziej złożonych sposobach. Tylko wyobraźnia może ograniczać sposoby robienia czegoś w sposób głupawo-złożony. Pozdrawiam, –

+2

Okej, nie musisz być niegrzeczny. Przynajmniej próbowałem na różne sposoby przed opublikowaniem tego. Chciałem tylko wiedzieć, czy jest inny sposób. Po prostu uczę się C++ atm. Dzięki za komentarz na temat istringstream, zamierzam spróbować zmieszać to z getline! Możesz opublikować jako odpowiedź, jeśli chcesz, a ja to zaakceptuję. – bb2

Odpowiedz

16

To może wyglądać następująco:

#include <iostream> 
#include <sstream> 
using namespace std; 

int main() 
{ 
    istringstream is("1\n2\n3\n4\n\n5\n"); 
    string s; 
    while (getline(is, s)) 
    { 
     if (s.empty()) 
     { 
      cout << "Empty line." << endl; 
     } 
     else 
     { 
      istringstream tmp(s); 
      int n; 
      tmp >> n; 
      cout << n << ' '; 
     } 
    } 
    cout << "Done." << endl; 
    return 0; 
} 

wyjściowa:

1 2 3 4 Empty line. 
5 Done. 

Nadzieja to pomaga.

+0

Muszę wiedzieć o pustym wierszu, ponieważ dane wejściowe są dzielone przez bloki oddzielone pustym polem. I muszę wiedzieć, jakie dane trafiają do jakiego bloku. – bb2

+2

@ bb2: W takim przypadku zdecydowanie użyłbym 'std :: getline', aby przeczytać każdą linię jako' string'. Następnie możesz utworzyć tymczasowy 'istringstream' w oparciu o ten ciąg i odczytać go. Edytowałem swoją odpowiedź. – LihO

+0

Właśnie zauważyłem, że to rozwiązanie zostało również polecone przez Alf P. Steinbach w komentarzu do twojego pytania. – LihO

4

Jeśli naprawdę nie chcesz używać getline, ten kod działa.

#include <iostream> 
using namespace std; 


int main() 
{ 
    int x; 
    while (!cin.eof()) 
    { 
     cin >> x; 
     cout << "Number: " << x << endl; 

     char c1 = cin.get(); 
     char c2 = cin.peek(); 

     if (c2 == '\n') 
     { 
      cout << "There is a line" << endl; 
     } 
    } 
} 

Należy jednak pamiętać, że nie jest to przenośne urządzenie. Gdy używasz systemu, który ma różne znaki końca linii niż "\ n", byłby to problem. Rozważ przeczytanie całych linii, a następnie wyodrębnij z niego dane.

+0

To nieprawda, że ​​nie jest to przenośne urządzenie. Nowy znak (y) systemu jest konwertowany na i z "\ n". – rasmus