Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange C bug in a simple program (homework)

Tags:

c

io

Below is some simple code that should accept integer input from the console. It works fine until invalid (non integer) input is given.

 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 }

Here is output from gdb that shows me stepping through the program after entering the value "g". Look at how it jumps to line 18, and then fails to look for further input from the user.

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) 

This is the output of the program once you give it bad input:

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

Could someone please help me figure out what I am doing wrong here?

like image 245
Jefferson Hudson Avatar asked May 23 '13 23:05

Jefferson Hudson


1 Answers

Inside your code, when you detect if(inp == 0), this actually means scanf() did not read anything, because the first token it found was not an integer nor whitespace. Therefore it did not advance on the input, and it is up to you to discard it, otherwise it gets stuck continuously not reading anything.

There are two easy ways you can fix it with scanf:

1) When you detect that inp == 0, just call a scanf("%*s"); to throw away the string token.

2) Read it into an array of char, and retrieve the integer value with atoi(str). For example:

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");
    }
    ...

Notice however, the second example above will treat input such as 10abc as an integer of value 10. You can do a quick scan through the data if you really want to enforce no non-integer characters are present. And I believe it is out of the scope of your homework, but you should be aware of problems regarding buffer overflows for the future :)

like image 63
i Code 4 Food Avatar answered Oct 13 '22 07:10

i Code 4 Food