0

Am aware that the difference between scanf() and gets() function is that scanf() continues to read the input string until it encounters a whitespace, whereas gets() continues to read the input string until it encounters a \n or EOF(end of file).

To see this difference in action, I tried writing a example on my own which is as follows:

                 #include <stdio.h>
                  int main()
                {    
                   char a[20];
                   printf("enter the string\n");
                   scanf("%s",&a);
                   printf("the string is %s\n",a);
                   char b[20];
                   printf("enter the string\n");
                   gets(b);
                   printf("the string is %s\n",b);
                   return 0;
                }

When the variable a was given the string "manchester united" as input, the output was:

                   enter the string
                   manchester united
                   the string is manchester
                   enter the string
                   warning: this program uses gets(), which is unsafe.
                   the string is  united

What I was expecting as output was just the first part of the string given to the variable a which is manchester and then, the program prompting me to enter the new input string for the variable b. Instead, I ended up with the above given output.

Based on the output, what I understand is:

It can be seen that as soon as scanf() encounters the whitespace, it stops reading the string thereafter, and thus, the remaining part of the string:united, has been assigned to the variable b,even without the program prompting me to enter the string for variable b.

How do I flush out the remaining part(the portion after the whitespace) of the string given to variable a?

so that, I can enter a whole new input string for the variable b.

Any further explanation on what is also happening here in the execution of the code will be greatly appreciated.

Apologies for the very basic mistakes(as it is evident by the responses)!! Just a novice to C programming:)

Arun
  • 65
  • 1
  • 9
  • 4
    First of all and before reading the question, `gets()` should not be used and it has been deprecated in recent versions of the [tag:c] standard. Your code has also multiple other issues like using `&` operator to pass an array for a `"%s"` specifier to `scanf()`. If the compiler, (*or runtime?, since I would never use `gets()` I didn't know there was a warning*) is issuing a warning why do you keep using it? – Iharob Al Asimi Jun 01 '16 at 19:24
  • 4
    **Never ever** use `gets`! It has even been removed from the C standard, which is really a rare event. – too honest for this site Jun 01 '16 at 19:30
  • `scanf("%s",b)` == `gets(b)` == a hole through which your user may crash or take control of your program – Petr Skocik Jun 01 '16 at 19:31
  • 2
    Your question is really "how do I used scanf when I actually don't want to do what scanf does". And the best answer is "don't use scanf". Use some function that reads a line if you really want to read a line, and then use something like `sscanf` to parse the line you read. – David Schwartz Jun 01 '16 at 19:32
  • @iharob: Is using `&` operator to pass an array for a `"%s"` specifier to `scanf()` invokes undefined behaviour ? I think so !!! – Destructor Jun 01 '16 at 19:56
  • "*... scanf() continues to read the input string until it encounters a whitespace ...*" -- This is specific to the `%s` format specifier. – Keith Thompson Jun 01 '16 at 20:39
  • You'll soon find, if you haven't already, that `scanf` really isn't very useful. You've already heard that `gets` is unsafe and should not be used at all. So the best thing you can do is take all the time you were going to spend struggling with `scanf`, and spend that time learning how to read entire lines with `fgets`, and then process those lines however you want. This may seem like a nuisance at first; you may find yourself thinking "but `scanf` is so much easier!" Trust me, `scanf` is *not* easier, at least, not if you want your input to actually work. – Steve Summit Jun 01 '16 at 23:26

1 Answers1

3

You can flush it by manually reading and discarding characters until you find a '\n' or someone hits the appropriate key combination to cause an EOF. Or you can ask scanf() to discard everything until a '\n' is found, the second one can be achieved like this

char string[20];
scanf("%19s%*[^\n]\n", string);

There are other things about your code, that are wrong

  1. You declare a as an array of 20 char and then you pass it's address to scanf() where it expects a pointer of char, the array name (the variable if you prefer) is automatically converted to a pointer to char when it's necessary.

  2. You used gets(), it's an old dangerous and deprecated function that is no longer a standard function. You should use fgets() instead which takes a parameter to perevent overflowing the destination array.

This is an example testing the suggested fixes

#include <stdio.h>

int
main(void)
{    
    char string[20];

    string[0] = '\0'; /* Avoid Undefined behaviour 
                         when passing it to `fprintf()' */

    scanf("%19s%*[^\n]\n", string);
    fprintf(stdout, "%s\n", string);

    fgets(string, sizeof(string), stdin);
    fprintf(stdout, "%s\n", string);

    return 0;
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • It is better to use `fscanf()` instead of problematic `scanf()`. – Destructor Jun 01 '16 at 19:57
  • 1
    @Destructor: The only difference between `fscanf()` and `scanf()` is that `scanf()` reads from `stdin`, while `fscanf()` takes a parameter specifying where it reads from. Did you mean to suggest reading a line using `fgets()` and then scanning it using `sscanf`? – Keith Thompson Jun 01 '16 at 20:41