[Courses] C Programming For Absolute Beginners, Lesson 2: Fun With Printf, Scanf, Puts, and Variables

Sachin Divekar ssd532 at gmail.com
Wed Feb 29 06:01:45 UTC 2012


On Wed, Feb 29, 2012 at 9:49 AM, Jacinta Richardson <
jarich at perltraining.com.au> wrote:

> On 29/02/12 13:06, Damián wrote:
>
>>
>> Hi Jacinta, thanks for your answer. I understood all of that (I think),
>> but I still don't get why in the original code:
>>
>> ====
>> scanf( "%d", &a );
>> puts( "Please enter another number up to three digits: " );
>> scanf( "%d", &b );
>> c = a + b;
>> printf("%d + %d = %d\n", a, b, c);
>> ====
>>
>> If you enter an invalid value in the first scanf, all the other lines are
>> run, except for the second 'scanf'. It doesn't wait for user input. I don't
>> see the relation between the first scanf returning 0 and the second not
>> running because of that condition.
>>
>>
> Oh!  I'm sorry, yes, that is much more clear.
>
> scanf() reads a value in from the STDIN input buffer.  Essentially this
> contains all of the stuff you type in, and that gets passed to the program
> each time you hit enter.  When scanf() runs, it starts at the start of the
> buffer and tries to find something there that matches what it is looking
> for.  It'll skip whitespace, but not other characters.  So if we type in:
>
>        "          123<newline>"
>
> (without the quotes, and where we hit the enter key to create a newline
> (also represented as "\n")) the first scanf() will skip all of that
> whitespace, see a number (123) and read that in.  At the end of this call
> to scanf(), the position in the buffer that we are up to is just before
> that newline/enter.  When the second scanf() runs, it sees that there is no
> data for it (there's only the newline) so it waits for further input.
>
> On the other hand, if we typed in:
>
>        "123 456\n"
>
> (without the quotes, and where \n is our newline (hitting the enter key))
> then the first scanf() will skip any leading whitespace (of which there
> isn't any) then then see a number (123) and read that in.  At the end of
> this call to scanf(), the position in the buffer that we are up to is the
> space before after the 3.  When we run the second scanf() it sees that
> there is still data in the buffer and it reads the next number 456 without
> waiting for further input.
>
> Something similar happens when we type in garbage data.  If we type in:
>
>        "no thanks"
>
> then the first scanf() sees that there isn't a number there for it, so it
> doesn't read anything in (and returns 0 for how many things it read in).
>  So the position of in the input buffer is still at that letter "n" in
> "no".  When the next scanf() happens it sees that there is still data in
> the buffer, so it reads from that and also fails to match a number,
> therefore also returning 0.
>
> This is actually really helpful.  It means that you can do the following:
>
>        if( scanf( "%d", &number) ) {
>                printf("You gave me a number!\n");
>        }
>        else if( scanf( "%s", &string) ) {
>                printf("You gave me a string!\n");
>        }
>
> I hope this helps.
>
>
>    J
>
>

Yes we can avoid such kind of problems by just discarding the user input by

nr = scanf( "%d",&a );
      if(nr<  1) {
          printf( "Invalid input.\n" );
          return 1;
      }

as stated by Jacinta.

But out of curiosity I searched for flushing the input stream buffer. One
solution is to
use fflush(stdin), but it is said that it does not fit into standards and
risky
to use.
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1052863818&id=1043284351


Then I found a less risky solution to flush input stream buffer.

//    using flush_i() to clear input stream buffer

#include<stdio.h>
int main()
       {

       void flush_i(void){

               int c;
               while (c != '\n' && c != EOF){
               c = getchar();
               }
       }

       int a, b, c;
       printf("Please enter any number up to three digits:" );
       scanf("%d", &a);

       flush_i();

       printf("You entered %d. Now enter another number up to three
digits:\n", a );
       scanf("%d", &b);

       c = a + b;
       printf("%d + %d = %d\n", a, b, c);

       return 0;
}


Here flush_i() discards everything upto the next new line in the input
stream buffer.

Even if we can discard the wrong input here, flush_i() might be useful
somewhere else.

--
Regards,
Sachin Divekar


More information about the Courses mailing list