2013-05-23 12 views
5

Poniżej znajduje się prosty kod, który powinien akceptować liczbę całkowitą wprowadzaną przez konsolę. Działa poprawnie, dopóki nie zostanie podane nieprawidłowe wejście (nie integer).Dziwny błąd C w prostym programie (praca domowa)

1 #include <stdio.h> 
2 
3 int main() 
4 { 
5 int x = 0; 
6 int inp = 0; 
7 int nums[20]; 
8 int idx = 0; 
9 for(;;){ 
10  printf("Enter an integer: "); 
11  inp=scanf("%d", &x); 
12  if(inp == 0){ 
13  printf("Error: not an integer\n"); 
14  } 
15  else{ 
16  if(idx<20){ 
17   nums[idx] = x; 
18   idx++; 
19  } 
20  } 
21 } 
22 return 0; 
23 } 

Oto wyjście z gdb, który pokazuje mi intensywniejszej poprzez program po wprowadzeniu wartości „g”. Sprawdź, jak przeskakuje do linii 18, a następnie nie szuka dalszych informacji od użytkownika.

Starting program: /Users/jeffersonhudson/xxxx/hw1 
Enter an integer: g 

Breakpoint 1, main() at hw1.c:12 
12   if(inp == 0){ 
(gdb) n 
13    printf("Error: not an integer\n"); 
(gdb) n 
Error: not an integer 
0x0000000100000ee4 18     idx++; 
(gdb) n 
10   printf("Enter an integer: "); 
(gdb) n 
11   inp=scanf("%d", &x); 
(gdb) n 

Breakpoint 1, main() at hw1.c:12 
12   if(inp == 0){ 
(gdb) 

Jest to wyjście z programu po nadać mu złe wejście:

Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
Enter an integer: Error: not an integer 
^C 

Czy ktoś mógłby mi pomóc dowiedzieć się, co robię źle tutaj?

+0

sądząc po wyjściu i śladu, Nie sądzę, żebyś wykonywał opublikowany kod. – LoztInSpace

+0

Zostawiłeś coś z przykładowego kodu, lub coś pomieszałeś w procesie odkażania - 'args' nie jest zdefiniowany. – duskwuff

+0

Przeprosiny. Zmieniłem argumenty na inp –

Odpowiedz

7

Wewnątrz kodzie, gdy wykryje if(inp == 0), to faktycznie oznacza scanf() nie czytać niczego, ponieważ pierwszy znak okaże nie był liczbą całkowitą ani spacji. Dlatego nie posunął się naprzód na wejściu, a od ciebie zależy, czy go odrzucić, inaczej utknie w sposób ciągły, nie czytając niczego.

Istnieją dwa proste sposoby, można go naprawić z scanf:

1) Gdy wykryje inp == 0, zadzwoń do scanf("%*s"); wyrzucić łańcuch tokenu.

2) Odczytaj do tablicy znaków i pobierz wartość całkowitą za pomocą atoi (str). Np jednak

int idx = 0; 
char aux[250]; // watchout for buffer overflows. 
for(;;){ 
    printf("Enter an integer: "); 
    scanf("%s", aux); // look at ways to avoid overflows here 
    inp = atoi(aux); 
    if(inp == 0 && aux[0] != '0'){ 
     printf("Error: not an integer\n"); 
    } 
    ... 

Zauważmy, drugi przykład powyżej będzie leczyć wejściowego takiego jak 10abc jako całkowitą wartości 10. Możesz wykonać szybkie skanowanie danych, jeśli naprawdę chcesz wymusić, że nie ma żadnych znaków całkowitych. I uważam, że jest poza zakresem swojej pracy domowej, ale trzeba zdawać sobie sprawę z problemów dotyczących przepełnienia bufora na przyszłość :)

+0

Co ze skokiem do linii 18? Blok else, w którym się znajduje, nie powinien być uruchamiany, więc jak się tam dostaliśmy? –

+0

@JeffersonHudson nigdy nie dojdziesz do linii 18 po wpisaniu czegoś, co nie jest liczbą. Utkniesz w linii 12 - 'if (inp == 0)' będzie prawdziwe i ** bum **. –

+0

Lub możesz zrobić "fgets", a następnie 'strtol' ... – rodrigo

-1

trzeba mieć wprowadzić nieprawidłowy znak, jak powrót przestrzeń/karetki/...

przepłukać stdin, aby wyczyścić bufor.

fflush(stdin) ANSI C

+0

Jesteś zbyt szybki. –

+2

I źle, też. 'fflush (stdin)' nie ma dobrze zdefiniowanego zachowania. –

+0

-1 Niezdefiniowane zachowanie. – michaelb958

-1
inp=scanf("%d", &x); 

zastępować

inp=scanf("%d", &x); 
while('\n'!=getchar()); 
+2

** gag ** ... naprawdę?!? –

+0

@NikBougalis Dosyć w tym. – BLUEPIXY