1

I'm trying to read a whole line using scanf multiple times and for some reasons it only works the first time. The second time the loop runs the compiler ignores the scanf function

Here is my code:

#include <stdio.h>
int main()
{
    char msg[100];
    char to[100];
    while (1)
    {
        printf("[]:Msg to ? :");
        scanf("%s", to);
        printf("[]:Msg: ");
        scanf("%99[^.]", msg);
        printf("Sending %s\n", msg);
    }
    return 0;
}

And this is the output Im given:

[]:Msg to ? :Him []:Msg: Hello mister him!. Sending Hello mister

him! []:Msg to ? :[]:Msg:

And here I was expecting to be able to change the variable to ... Adding a space before %s for some reason has no effect here

Community
  • 1
  • 1
Ionut Eugen
  • 481
  • 2
  • 6
  • 27

2 Answers2

1

The problem is here:

scanf("%99[^.]", msg);

This statement reads up to 99 characters, but only until the next non-matching character. Now if you put

Hello mister him!.

into the input buffer, you indeed have

"Hello mister him!.\n"

in the stdin input stream buffer. Now, the scanf processes everything up to (but not including) the dot, so the dot and the newline remains in the input buffer. The next call to scanf()

scanf("%s", to);

now fetches the dot and the newline from the output buffer, which automatically concludes the next line to read. Now the input buffer is empty and the following scanf waits for the next message.

To fix this, you can skip the dot and the newline like this:

scanf("%99[^.]", msg);
getchar(); // Pacman (Eat the dot)

and in the other scanf use

// scanf(" %s", to); // Skip the preceding newline

(this is unnecessary, as H.S. pointed out)

Please note, that the case of an input message >99 chars is not handled properly yet.

Ctx
  • 18,090
  • 24
  • 36
  • 51
0

If you wants to read a whole line using scanf you can use %[^\n] instead of %99[^.]. And make sure to add a getchar() if any 'enter' is pressed just before scanning with %[^\n]. The changes showed in the code bellow may be useful:

while (1)
{
    printf("[]:Msg to ? :");
    scanf("%[^\n]", to);
    getchar();
    printf("[]:Msg: ");
    scanf("%[^\n]", msg);
    getchar();
    printf("Sending %s\n", msg);
}
Niloy Rashid
  • 687
  • 4
  • 16
  • `scanf("%[^\n]", to);` 1) fails to read anything into `to` when the line of input is `"\n"`, leaving `to` in an uninitialized state. 2) The lack of a _width_ like `"%99[^\n]"` renders this code as bad a `gets()`. – chux - Reinstate Monica Jan 16 '19 at 16:50