2017-02-23 45 views
14

Próbuję wykonać ten blok kodu.Dlaczego druga funkcja scanf() nie wykona

#include <stdio.h> 
int main(void) 
{  

    printf("Start from here\n"); 
    int e, f, g, h; 

    scanf("%d,%d", &e, &f); 
    scanf("%d, %d", &g, &h); 

    printf("%d %d %d %d", e, f, g, h); 
} 

Kiedy wejście 2,0 lub coś, co odpowiada ciąg formatu w pierwszej scanf(), drugi scanf() wykonuje również.

Jednakże, jeśli wejście coś 2-0 w pierwszym scanf(), program pomija drugi scanf() i idzie prosto do printf()

Na przykład, tutaj jest wejście i wyjście z biegiem próbki programu. Druga linia to dane wejściowe.

Start from here 
1-2 
1 0 -2 -856016624u 

Wskazówki jak program całkowicie pominięty drugi scanf() i poszedł prosto do printf(). Dlaczego tutaj pomijany jest drugi scanf()?

+1

'1-2' powinno być' 1, -2'? To znaczy przecinek między liczbami. Ponieważ właśnie tak powiedziałeś 'scanf'. – kaylum

+3

Twój drugi 'scanf' jest wykonywany.'e' pobiera' 1' i 'g' dostaje' -2' –

+1

Dlaczego nie sprawdzasz wartości zwracanych przez 'scanf'? Może być przydatny do przeczytania strony podręcznika –

Odpowiedz

1

W kodzie scanf("%d, %d",&e,&f) jest w ten sposób, więc należy dać swój wkład jak: 1,2 lub 2,3 itp

Jeśli chcesz, aby wejście należy podać jak 0-2 lub 2-4, wówczas scanf musi być tak : scanf("%d-%d",&e,&f).

W ten sposób nie zostanie pominięty.

21

Ciąg znaków w formacie dotyczy także nie-formatujących specyfikatorów. Gdy napiszesz "1-2", pierwszy scanf odczyta "1", a następnie poszukaj przecinka. Nie znajdzie takiego, więc się poddaje. Teraz drugi scanf zobaczy "-2", a następnie poszukać przecinka. Nie znajdzie takiego, więc się poddaje.

Rezultat końcowy jest taki, że pozostałe dwie zmienne nie zostaną ustawione, dzięki czemu staną się czymkolwiek, co znajduje się w ich pamięci w czasie wykonywania.

Można tego uniknąć, sprawdzając wartość zwracaną przez scanf. Powie Ci, ile wartości udało się znaleźć. Spróbuj tego:

#include <stdio.h> 
int main(void) 
{  

    printf("Start from here\n"); 
    int e, f, g, h; 

    if (scanf("%d,%d", &e, &f) != 2) { /* error handling */ } 
    if (scanf("%d, %d", &g, &h) != 2) { /* error handling */ } 

    printf("%d %d %d %d", e, f, g, h); 
} 
+5

Uwaga: W ramach * obsługi błędów * może być konieczne odrzucenie danych wprowadzanych przez użytkownika! Można to zrobić za pomocą pętli 'getchar' lub' scanf ("% * [^ \ n]"); getchar(); 'na przykład ... – Sebivor

+5

Pamiętaj również: przestrzeń, w tym przypadku, jest semantycznie pozbawiona znaczenia; oba ciągi formatów są funkcjonalnie równoważne, ponieważ '% d' domyślnie odrzuca wiodące białe znaki * tak czy inaczej *. – Sebivor

+0

Dobrze wiedzieć, usunięto bit o ciągach formatujących. –

2

Usuwanie przecinek pomiędzy dwoma specyfikacją formatu.

scanf("%d %d", &e, &f); // Remove comma in first argument of scanf 
scanf("%d %d", &g, &h); // Remove comma in first argument of scanf 
     ^^^ 
     Remove comma between two numbers 

Ponieważ scanf pominie tylko spacje a comma nie spacje.

Co się dzieje, gdy pytasz scanf, czy odczytać dane numeryczne, oznacza, że ​​najpierw pomija wszelkie znalezione białe znaki, a następnie odczytuje znaki, dopóki znak, który czyta, nie może stanowić części numeru.

W takim przypadku, po napotkaniu przecinka, przestaje czytać. Ponieważ nie odczytał żadnych cyfr, nie ma numeru, który mógłby zapisać, więc po prostu pozostawia oryginalną wartość.