Thread: Getting char as input by scanf

  1. #1
    Registered User
    Join Date
    Mar 2014
    Posts
    6

    Getting char as input by scanf

    In GCC v4.6, I am encountering a strange problem. If I try to get a character input and a int input like this:
    Code:
    int main()
    {
    int a;
    char b;
    scanf("%d",&a);
    scanf("%c",&b);
    }
    the compiled program asks for input only one time. On the other hand, if I do the char scanf earlier like this:
    Code:
    int main()
    {
    int a;
    char b;
    scanf("%c",&b);
    scanf("%d",&a);
    }
    it asks for input twice. Any idea why this behaviour?

  2. #2
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    I think it has something to do with a whitespace character (the enter you hit after entering your integer is being stored in the char b). One way I would handle it would be to have something like:
    Code:
     scanf("%d\n",&a);

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It is because %c format picks up whitespace as characters.

    A common solution is to add a space to the format string to skip any whitespace (a space instead of the '\n' in Spork's post). A robust solution is to use fgets() to read a line of input into an array of char, and then check the contents of the complete line (using sscanf() if one wishes).

    Incidentally, you could have worked this out by printing a and b (using the %d format for both, so a newline results in visible output).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Mar 2014
    Posts
    14
    Scanf() is a function not really recommended for input because of the kind of issue you are having with your code. What you have to realize is that scanf sure is good for reading input but it has a side-effect when used with anything other than integers, that it also reads new line (\n) characters from the input stream (in this case stdin). So when you are doing a scanf of a character followed by an integer, it is leaving behind the new line character in the stdin buffer which is then read by the following integer scanf call. My code below will show 2 inputs.

    Code:
        int a;
        char b;
    
    
        scanf("%c", &b);
        getchar();
        scanf("%d", &a);
    This is because getchar(); in between the two scanf will read the rubbish new line character that we do not care about.
    Last edited by Kotik; 03-31-2014 at 07:57 AM.

  5. #5
    Registered User
    Join Date
    Mar 2014
    Posts
    6
    @Kotik This by far is the most ingenious solution. Thanks.

  6. #6
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by Kotik View Post
    Scanf() is a function not really recommended for input because of the kind of issue you are having with your code. What you have to realize is that scanf sure is good for reading input but it has a side-effect when used with anything other than integers, that it also reads new line (\n) characters from the input stream (in this case stdin). So when you are doing a scanf of a character followed by an integer, it is leaving behind the new line character in the stdin buffer which is then read by the following integer scanf call. My code below will show 2 inputs.

    Code:
        int a;
        char b;
    
    
        scanf("%c", &b);
        getchar();
        scanf("%d", &a);
    This is because getchar(); in between the two scanf will read the rubbish new line character that we do not care about.
    The second scanf will skip the new line anyway because it is waiting for an integer, not a char.

    If you wanted to discard a character you can use the '*' in the scanf statement -> This discards the input
    Code:
    sscanf("%d%*c", &apple);
    However, you are assuming that the user won't accidentally type the wrong thing.

    Another thing you can do is:
    Code:
    int ch;
    
    while ((ch = getchar()) != '\n' && ch != EOF)
    {
      continue;
    }
    That way you can get rid of everything in the input buffer (most of the time) - For more info, FAQ > Flush the input buffer - Cprogramming.com
    Fact - Beethoven wrote his first symphony in C

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by namandixit View Post
    @Kotik This by far is the most ingenious solution. Thanks.
    It's also one that can confuse a user since the program behaviour will change depending on small changes of user behaviour.

    getchar() and scanf() have different styles of input (read characters directly, versus interpret data in the stream according to a format string).

    Generally speaking, mixing styles of input on one stream is a REALLY bad idea.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. input while/scanf
    By Tigertan in forum C Programming
    Replies: 1
    Last Post: 08-25-2012, 05:50 AM
  2. Can't scanf char
    By krakatao in forum C Programming
    Replies: 3
    Last Post: 04-11-2012, 08:41 AM
  3. input using scanf()
    By kizyle502 in forum C Programming
    Replies: 5
    Last Post: 09-10-2009, 12:56 AM
  4. Input and Scanf
    By DAaaMan64 in forum C Programming
    Replies: 3
    Last Post: 01-14-2009, 06:56 PM
  5. help with input and scanf
    By kpw in forum C Programming
    Replies: 9
    Last Post: 08-28-2001, 08:21 PM

Tags for this Thread