2011-01-17 8 views
8

Załóżmy, że mam wejście następująco:Korzystanie ifstream jak fscanf

N (X_1,Y_1) (X_2,Y_2) .... (X_N, Y_N) 

gdzie N X_i i Y_i są liczbami całkowitymi.

Przykład:

2 (55,1) (521,7) 

Aby to czytać, mogę zrobić coś takiego (zakładając wszystkie zmienne są zdefiniowane, itd.):

fscanf(fin,"%d ",&N); 
for (int i = 0; i < N; i++) 
    fscanf(fin,"(%d,%d) ", &X[i], &Y[i]); 

Chodzi o to, w jaki sposób mogę zrobić to łatwo za pomocą ifstream. Mogę uzyskać ciąg, a potem mogę pozbyć się niepotrzebnych i używając stringów, mogę uzyskać dwie liczby, ale wydaje się to trochę uciążliwe. Czy istnieje łatwiejszy, bardziej elegancki sposób?

Dzięki

+0

dlaczego nie wystarczy użyć scanf jak jesteś już robi? czy pytasz, ponieważ chcesz się uczyć? – falstro

+0

Pytam tylko dlatego, że chcę się uczyć =) – kolistivra

+3

Ostatnim razem, gdy zasugerowałem użycie IO w stylu C w programie C++, wszystkie elity C++ na SO miały na mnie ochotę. – dreamlax

Odpowiedz

6
int n, x, y; 
char c; 
if (is >> n) 
    for (int i = 0; i < n; ++i) 
     if (is >> c && c == '(' && 
      is >> x && 
      is >> c && c == ',' && 
      is >> y && 
      is >> c && c == ')') 
     { 
      X[i] = x; 
      Y[i] = y; 
     } 
     else 
      throw std::runtime_error("invalid inputs"); 

Można uprościć wszystkie ważne wewnętrzną if stan wyżej ...

is >> chlit('(') >> x >> chlit(',') >> y >> chlit(')') 

... z prostego typu wsparcia dla spożywania specyficzny charakter:

struct chlit 
{ 
    chlit(char c) : c_(c) { } 
    char c_; 
}; 

inline std::istream& operator>>(std::istream& is, chlit x) 
{ 
    char c; 
    if (is >> c && c != x.c_) 
     is.setstate(std::iostream::failbit); 
    return is; 
} 

Zobacz pełny program ilustrujący to on ideone here.

Stary post zrobił coś podobnego do spożywania konkretnych ciągów. (Powyższe chlit może być szablonem, ale chlit<','>() jest brzydki do odczytu i zapisu - wolałbym zaufać kompilatorowi).

+0

Od 3 linii do 15. . . Naprawdę lubię C++, ale czasami iostreams może być trudny do pracy. – dreamlax

+0

cóż, przynajmniej nie spowoduje to nadpisania pamięci, jeśli na wejściu jest coś nieoczekiwanego. –

+0

@Anders: fscanf przestaje skanować przy nieoczekiwanym wprowadzeniu i zwraca liczbę pomyślnie przeskanowanych elementów. – dreamlax

3
cin >> N; 
for (int i = 0; i < N; i++) 
{ 
    cin.ignore(100,'('); 
    cin >> X[i]; 
    cin.ignore(100,','); 
    cin >> Y[i]; 
    cin.ignore(100,')'); 
} 

Może obsługiwać spacje również, jak można odczytać wejście jak:

2 ( 1 , 3 ) ( 5 , 6 ) 

prezentacja na ideone: http://www.ideone.com/hO0xG

Powiązane problemy