1

I have the following code:

#include <stdio.h>
int opt;
scanf("%d",&opt);
while(opt!=0)
{
    switch(opt)
    {
    case 1:func1();
        break;
    case 2:func2();
        break;
    case 3:return 0;
    }
    printf("\n");
    scanf("%d",&opt);
}

I want to computer to get from user everytime different digit (1 or 2 or 3) and in every time the computer will run on seperate function. but when I press 2, func2 gets 3 ints and prints chars on the screen in a new line. the computer reads them instead of reading next input (1 or 2 or 3). how can I fix it?

EDIT: The problem rises only after specific inputs (I build a program converts bases).

Input:

2

10

26

1z2

OUTPUT:

ERROR

INPUT:

2

38762

10

UNWANTED OUTPUT:

201222

I'm not sure from where the computer scans the second num it uses to print the last unwanted output.

haccks
  • 104,019
  • 25
  • 176
  • 264
Danis Fischer
  • 375
  • 1
  • 7
  • 27

4 Answers4

1

your second scanf is supposed to block but it isn't because the input buffer is not empty after the first call! This is why it is always returning the previous value and looping infinitely. Use a combination of fgets and sscanf instead.

Also check this : http://c-faq.com/stdio/scanfprobs.html

H_squared
  • 1,251
  • 2
  • 15
  • 32
  • I don't i'm allowed to do so. however what is the difference between scanf and fgets except security issues? – Danis Fischer Nov 20 '13 at 12:39
  • 1
    fgets reads input from stdin and stores it in an array. Then you can parse it using sscanf. scanf is really bad, because once you hit `enter` it won't read new inputs because it will always detect `enter`pressed in the buffer. Check the link in my answer it can explain why in more detail. – H_squared Nov 20 '13 at 12:42
1

If your functions use scanf() inside them to ask for characters or you are using fgets() to read a while line, you might find that scanf() / fgets() does run without user input. This is because the newline character you entered at scanf("%d",&opt); is still there and is used as new input for the next scanf()/fgets(). You have to erase it by issuing

fflush (stdin);

Just prior to call scanf() or fgets()

mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32
  • 3
    `fflush (stdin);` is undefined behavior http://stackoverflow.com/questions/2187474/i-am-not-able-to-flush-stdin – StoryTeller - Unslander Monica Nov 20 '13 at 12:50
  • @StoryTeller Correct. Although he is right about clearing stdin, I would rather use `fgets` and insert an `\0` at the beginning of the buffer, so the next `fgets` call blocks. `sscanf` can then be used to parse the integer – H_squared Nov 20 '13 at 12:55
  • `fflush(stdin)` has a documented behavior for both input and output streams, at least for Windows, according to the MSDN: http://msdn.microsoft.com/en-us/library/9yky46tz.aspx – mcleod_ideafix Nov 20 '13 at 13:44
  • 1
    @mcleod_ideafix It is extended by microsoft as explained in the example code. It is non-standard in C and therefore not portable. `fflush` can only be used on output streams as explained here: http://c-faq.com/stdio/stdinflush.html – H_squared Nov 20 '13 at 14:43
  • @Coargu Aliquis `char buffer[512]=""; fgets(buffer,sizeof(buffer),stdin);` this reads the input and stores it in buffer as a series of characters (aka string). You will have to use `sscanf` afterwards to get the integer since `scanf` does not allow you to specify from where you want to read. Also once you are done with the input you will have to delete it by `buffer[0]='\0';` Haccks's solution should work by the way. – H_squared Nov 20 '13 at 14:50
1

you may need something like this..

#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char *argv[])
{
    int opt;

    do{
        printf("Enter the option\n");
        scanf("%d",&opt);
        switch(opt){
            case 1: func1();
                    break;
            case 2: func2();
                    break;
            case 3: 
                    return 0;
        }

    }while(opt != 3);

    return 0;
}
Raju Kunde
  • 982
  • 1
  • 8
  • 18
0

One problem that is pointed out by hhachem in comment that you are not exiting from your while loop.
You can solve this problem by doing (as you want to exit only after pressing 3):

 while(1)
{
    switch(1)
    {
        case 1:func1();
            break;
        case 2:func2();
            break;
        case 3: exit(0);
    }
    printf("\n");
    scanf("%d",&opt);
}  

Test program:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int opt;
    scanf("%d",&opt);
    while(1)
    {
        switch(opt)
        {
            case 1:printf("1");
                   break;
            case 2:printf("2");
                   break;
            case 3:exit(0);
         }

         printf("\n");
         scanf("%d",&opt);
    }

    return 0;
}  

See the output.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264