Thread: strange situation with scanf, char , etc...

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

    strange situation with scanf, char , etc...

    hi everybody,

    i am gonna give you some code blocks and some of them works and some does not, but all of them eventually same thing. if you can solve the situation i will be happy about that. thanks,

    These is WORK fine #1
    and these is my best solution but why????
    Code:
    #include<stdio.h>
    
    int main(int argc, char *argv[])
    {
    
    	int a,b;
    	char c;
    	
    	scanf("%d", &a);
    	scanf("%d", &b);
    	fflush(stdin);
    	scanf("%c", &c);
    	printf("%d %c %d = %d\n", a, c, b, c=='+' ? a+b : a-b);
    	
    
    return 0;
    }

    These is WORK fine #2
    Code:
    #include<stdio.h>
    
    int main(int argc, char *argv[])
    {
    
    	char c;
    	int a,b;
    	
    	scanf("%d", &a);
    	scanf("%d", &b);
    
    	scanf("%s", &c);
    	printf("%d %c %d = %d\n", a, c, b, c=='+' ? a+b : a-b);
    	
    
    return 0;
    }
    These is WORK fine #3
    Code:
    #include<stdio.h>
    
    int main(int argc, char *argv[])
    {
    
    	char c;
    	int a,b;
    	
    	scanf("%d", &a);
    	scanf("%d", &b);
    
    	scanf(" %c", &c); // there is one space before %c. it is its difference then code 5
    	printf("%d %c %d = %d\n", a, c, b, c=='+' ? a+b : a-b);
    	
    
    return 0;
    }
    These is does NOT WORK #5
    Code:
    #include<stdio.h>
    
    int main(int argc, char *argv[])
    {
    
    	char c;
    	int a,b;
    	
    	scanf("%d", &a);
    	scanf("%d", &b);
    
    	scanf("%c", &c);
    	printf("%d %c %d = %d\n", a, c, b, c=='+' ? a+b : a-b);
    	
    
    return 0;
    }
    These is does NOT WORK #6
    Code:
    #include<stdio.h>
    
    int main(int argc, char *argv[])
    {
    
    	int a,b;
    	char c; // char c is down from int a,b is difference then code 2
    	
    	scanf("%d", &a);
    	scanf("%d", &b);
    
    	scanf("%s", &c);
    	printf("%d %c %d = %d\n", a, c, b, c=='+' ? a+b : a-b);
    	
    
    return 0;
    }

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    6
    i compile on ubuntu 12.04 gcc 4.6.3 also Windows 7 Dev C++ and Windows 8 Dev C++

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    The results of your test can be explained here:

    FAQ > How do I avoid a "dangling" newline when reading single character user input? - Cprogramming.com

    Let's assume the following:

    Code:
    // "Input 1"
    
    1
    2
    +
    
    // "Input 2"
    
    1 2 +



    #1: According to the standard, this does not have to work, as using "fflush()" on an input stream is undefined behavior. However, some compilers do allow this. It is non-portable and considered poor practice, though.

    FAQ > Why fflush(stdin) is wrong - Cprogramming.com

    It appears you're getting lucky, and "fflush(stdin)" is actually flushing the input buffer for you (which, as I mentioned, isn't necessarily a guarantee). Therefore, the input buffer is clear when you read a character, so it will grab the next character ('+' or '-') and behave as expected.

    This is true for "Input 1" and "Input 2".




    #2: '%s' will read a sequence of non-whitespace characters, the first such character would be the '+' or '-' (for both "Input 1" and "Input 2"), and is stored accordingly. However, '%s' will attempt to terminate the input with a null character, for which you don't have space for (the variable not being an array), so this is not a good idea.

    scanf - C++ Reference




    #3: The space before the "%c" tells the "scanf()" to ignore leading whitespace before reading a character. This is covered in the link provided at the top of this post as a solution for the issue you're tinkering with.




    #5: This does not work for "Input 1" or "Input 2" because there is whitespace (a newline or space, respectively) immediately after the number, and that is the character read by the "scanf()".

    Try running this code with the following input:

    Code:
    1 2+
    With no whitespace after the integer, you will see that it works. For further enjoyment, try it with this modification:

    Code:
    // enter the following input:
    // 1 2 +
    
    #include<stdio.h>
     
    int main(int argc, char *argv[])
    {
     
        char c;
        int a,b;
         
        scanf("%d", &a);
        scanf("%d", &b);
     
        scanf("%c", &c);
    
        if(c == ' ')
            puts("Space!  '+' was not scanned!");
    
        printf("%d %c %d = %d\n", a, c, b, c=='+' ? a+b : a-b);
         
     
    return 0;
    }



    #6: If I run this with "Input 2", I see the result is "1 + 0 = 1". If I'm not mistaken, that zero is because the variable is overwritten with the null terminator appended by '%s' (mentioned in #2). As a test, I entered the following:

    Code:
    1 2 +2
    
    // result:
    // 1 + 50 = 51
    The "50" is the ASCII integer value that represents the character '2', illustrating that the '%s' is indeed overwriting other variables since you're not giving enough room (i.e. an appropriately sized array) for a string.

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    6
    Thank you for explanation. Now i have another question.

    for these code which is you gave me as an example

    Code:
    // enter the following input:
    // 1 2 +
     
    #include<stdio.h>
      
    int main(int argc, char *argv[])
    {
      
        char c;
        int a,b;
          
        scanf("%d", &a);
        scanf("%d", &b);
      
        scanf("%c", &c);
     
        if(c == ' ')
            puts("Space!  '+' was not scanned!");
     
        printf("%d %c %d = %d\n", a, c, b, c=='+' ? a+b : a-b);
          
      
    return 0;
    }
    why %c takes the space character. should not it pass the white spaces and directly take the + or - char. for example if i write

    scanf("%d");
    scanf("%d");

    it pass the white spaces between two integers.

    OR

    scanf("%s");
    scanf("%s");

    it pass too,

    but why it does not work for %c. thank you very much for your interest.

  5. #5
    Registered User
    Join Date
    Mar 2011
    Posts
    6
    and also i didn't understand why fflush is wrong
    i read these
    FAQ > Why fflush(stdin) is wrong - Cprogramming.com
    but i couldn't understand would you explain me? thanks

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The simple answer: it results in undefined behaviour. Undefined behaviour is a Bad Thing.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    6
    is undefined behaviour means it can be clear stdin buffer or it can not.
    or it clear but other results can be anything

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    It means that if you try the same thing using another compiler, or another OS, that what you thought was a "really good idea" is now a case of "WTF just happened!?"
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Mar 2011
    Posts
    6
    ok thanks

  10. #10
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Chinacolt View Post
    why %c takes the space character. should not it pass the white spaces and directly take the + or - char. for example if i write

    scanf("%d");
    scanf("%d");

    it pass the white spaces between two integers.

    OR

    scanf("%s");
    scanf("%s");

    it pass too,

    but why it does not work for %c. thank you very much for your interest.
    %c reads the next character in the input buffer, thus it makes sense to not skip whitespace (most of the other specifiers don't just skip space but also '\t' (tabs), '\n' (newlines), '\r' (carriage return), '\f' (form feed) and '\v' (vertical tab) - i.e. all characters for which isspace() returns true) because there are situations where you want to know whether the next character is a whitespace. %c just treats every character the same.

    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strange scanf behaviour
    By cavva in forum C Programming
    Replies: 3
    Last Post: 08-10-2009, 12:44 PM
  2. strange linker situation
    By mynickmynick in forum C Programming
    Replies: 2
    Last Post: 04-21-2009, 07:22 AM
  3. scanf acting strange...
    By Tyrant in forum C Programming
    Replies: 2
    Last Post: 11-18-2007, 06:07 PM
  4. Strange scanf behavior
    By exvor in forum C Programming
    Replies: 7
    Last Post: 07-25-2005, 11:54 AM
  5. Strange behaviour of scanf()
    By chris1985 in forum C Programming
    Replies: 3
    Last Post: 01-15-2005, 02:41 PM