[C language ] Insidious newlines on input


While doing the last exercise in Chapter 7, I ran into a problem reading an input line if it contains a newline. Everywhere this is explained somewhat abstrusely, I will try on my fingers:

The problem is that when you type any input into scanf from the keyboard – besides characters (letters, numbers, etc.) – you also _always_ send a /n character to the incoming stream – that is, a newline.

For example, the program contains the scanf operator ("%c", &n);

You press the q key on your keyboard and then the Enter key to send the value to the program…

What is included in the program? It is logical to assume that there will now be only q. Indeed, q becomes the value of the variable n. But actually something else – you sent to the input stream (also called stdin) and the Enter key, which can be interpreted as \n.. Let’s take another example:

#include <stdio.h>
int main (void)
{
int z, x;

scanf ("%c", &z);
printf("%c", z);

scanf ("%c", &x);
printf("%c", x);

return 0;
}

Now let’s run the program and…

  1. Press the a key, then press the Enter key
  2. The symbol a will be displayed on the screen
  3. Now press the b key, then press the Enter key
  4. b will not be displayed on the screen, there will only be an empty line

And here is the same situation through the eyes of the program:

  1. I request the value of the variable z
  2. User enters a and \n
  3. I assign the value a to the variable z
  4. Outpit to screen a
  5. Requesting the value of a variable x
  6. User inputs b and \n
  7. I see that in the input stream is \n b \n
  8. I take the following character from the input stream: \n and assign it to a variable x
  9. Displaying a newline character (\n)
  10. At the same time b \n remains in the flow

…which will forever lie in this buffer (this is the name of the input stream, which is already stored in the program memory).

What should I do to avoid such errors?

  1. remember that scanf (and of course getchar) does not skip service characters (including \n) when entering characters %c, as well as %[...] and %n. In other cases, you can not worry, for example, scanf ("%d", x) – does not pay attention to \n (so do not use something like scanf ("%d\n", x) in any case) .
  2. clear buffer. As they say: cleanliness is the key to health (go take a shower or what?). There are many ways to do this, for beginners I recommend doing this:
    while (getchar() != '\n')
    	continue;

    What happens in this case is that the loop takes out characters one by one from the input stream and compares whether this is a line break. If not, then it goes to continue;, which returns the program to the beginning of the loop and again takes out another character and compares again. And so on until it encounters \n; at the same time, when it does meet \n, the loop will already get it from the buffer (i.e. it will clear the buffer, it will become empty), and the loop will stop → your program will continue execution.

    There are other ways to flush the buffer, such as the fflush(stdin) function, but be sure to read the documentation before using it.

Happy to see your comments!


This entry was posted in C language (en). Bookmark the permalink.

Leave a Reply

🇬🇧 Attention! Comments with URLs/email are not allowed.
🇷🇺 Комментарии со ссылками/email удаляются автоматически.