C scanf() and fgets() problem
Asked Answered
P

4

5

I'm trying to read user input and store it as a string including the whitespace. I did a search for a solution and was pointed to fgets() or scanf(%[^\n], str). But both these solutions give me an error.

This is what I have:

//MAX_CHARACTERS is set to 30

 scanf("%d", &input);
 if (input == 1){
        int pr;
        char na[MAX_CHARACTERS+1];
        printf("\nEnter the name: ");
        scanf("%[^\t\n]", &na);
        while (strlen(na)>MAX_CHARACTERS){
            printf("\nName is too long, enter new name: ");
            scanf("%[^\t\n]", &na);
        }// end na check
        printf("\nEnter priority: ");
        scanf("%d", &pr);
        while (pr>MAX_PRIORITY || pr <MIN_PRIORITY){
            printf("\nBad priority, enter new priority (0-100): ");
            scanf("%d", &pr);
        }//end pr check

It works fine if I use %s in all instances of %[^\t\n] but when I use %[^\t\n] or

fgets(na, 30, stdin), it skips the first scanf for name and goes straight to "Enter priority: ". Then when I print, I have a blank name with whatever priority I entered.

EDIT: Sorry, the missing quotes on the first scanf is a typo. Not a cause of the problem. I typed in '1' for the first scanf("%d", input).

FIXED IT

Since it won't let me post an answer yet,

Someone figured it out. Incase anyone's still interested, the problem was the first scanf().

scanf("%d", &input);

It is leaving a \n in the buffer. The second one is taking the \n and reading it as an input so it gets skipped.

SOLUTION:

Putting a

fflush(stdin); //right after the if statement seems to have fixed the issue. 

Thanks for everyone's help.

Penicillium answered 14/8, 2011 at 23:57 Comment(6)
you're missing quotes in the first scanf. Typo?Sansculotte
What do you type for the first scanf (the &input one)? 1ENTER or 1corilENTER? :)Grosswardein
I don't understand scanf very well, but for reading a string your argument should be a char*, i.e. either na or &na[0]. But I don't see a %s format specifier anywhere.Sophister
Could you put your "Solution part" in an answer instead of in the question?Homemaking
No fflush(stdin); is not the solution. The behavior of fflush() on an input stream is undefined. If you've left characters in the input buffer, you need to read them. A more general solution is to use fgets() to read a line of text into a string, then sscanf() on the string to extract data from it. (sscanf() has potential problems with numeric input, but we can leave that for later.)Unger
And don't forget to check the value returned by either scanf() or sscanf(). (Think about what (scanf("%d", &input); will do if the input isn't a number.)Unger
S
7

This is the problem with using scanf() to take in user input, it's not made to handle strings or any bad inputs. scanf() is meant to read formatted input (e.g., files with a strict and specific format). When taking in input from the user, input could be malformed and causes problems. You should use fgets() to read the input and parse it yourself.

To answer why the second scanf() call gets skipped, it's because the first call only consumes the digits that gets inputted. However the newline from pressing Enter remains in the input buffer and is in turn, the input of the second call. To fix this, you'd want to remove that newline character from the input buffers. The safest way to do that would be to use getchar() until the newline character is read, then continue with your program. And avoid using the fflush(stdin) pattern, that's not safe and can cause more problems than it's worth.

Here's a simple function you can use to read characters until a newline is read:

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

Call this after any call to scanf() that you're processing non-string data.

Shirting answered 15/8, 2011 at 1:25 Comment(0)
D
2
    scanf("%d",&choice);
    fgetc(stdin);

what i did is to read the fgetc from stdin and this leave the '\n' so your buffer is crear.

Dentoid answered 2/8, 2013 at 15:39 Comment(0)
R
0

the first line of the code:

scanf(%d, &input);

should be :

scanf("%d", &input);

i.e. the quotes are missing

Respective answered 15/8, 2011 at 0:1 Comment(0)
B
0
scanf("%[^\t\n]", &na);

should be:

scanf("%[^\t\n]", na);

ie., remove the &

Also fgets should work fine except that it will include the newline from when the user presses enter. You will have to strip it off.

Barnabe answered 15/8, 2011 at 0:28 Comment(1)
It's still skipping the first scanf("%[^\n]", na); when I remove the &.Penicillium

© 2022 - 2024 — McMap. All rights reserved.