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:

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 replace scanf() with fgets(na, 30, stdin), it skips the first scanf for name and goes straight to "Enter priority: ".
Then when it prints, I get a blank name with whatever priority I entered.

nvm fixed it.

incase anyone's having the same or similar issue.


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.

Wrong solution!!!! Do not use fflush(stdin); . Here's why.

And when asking a question, "... these solutions give me an error" is not an appropriate message to give us. There are hundreds of errors -- be specific, both in the exact error message, and the line the error is on.

fflush() on any input stream, like stdin, is deprecated, so it may very well not work at all. Use it on output streams only. ("Flush the toilet, not the kitchen faucet.")

To pull the remaining newline char off the input stream, you can use:

getchar();

right after the scanf() line of code.

Since you know that a newline will always be there, the program will not pause here. It just grabs the newline char, and goes on.

Edited 5 Years Ago by Adak: n/a

fflush() on any input stream, like stdin, is deprecated,

As far as I know, flushing an input stream was never reprecated (or whatever :icon_mrgreen:), it was never legal -- standards-wise. If it was, why would they remove it? And when?

By error, I should have been more specific, it compiles but when it runs, it doesn't work as intended (skips the next scanf()). getchar() also solves the problem.

By error, I should have been more specific, it compiles but when it runs, it doesn't work as intended (skips the next scanf()). getchar() also solves the problem.

Which doesn't invalidate the advice to avoid calling fflush() on input streams. getchar() solves the problem as well, but you might consider throwing it into a line-based loop to catch everything rather than just the next bogus character:

void clear_line(FILE *in)
{
    int ch;

    do
        ch = getc(in);
    while (ch != '\n' && ch != EOF);

    /*
        Clear the status if we caused an end-of-file
        state, but propagate an error state
    */
    if (ch == EOF && !ferror(in))
        clearerr(in);
}

One thing to keep in mind is that fflush(stdin) (when it works) doesn't block, but getchar() does. So if the stream is empty and you do something like clear_line(), it will wait for input rather than act as a no-op. There's no portable way to fully simulate the behavior of fflush(stdin), but you can sidestep the need for it by using line input (fgets is the usual recommendation) followed by in-memory parsing (such as with sscanf()) rather than forcing the input function to parse your data too.

Edited 5 Years Ago by Narue: n/a

This article has been dead for over six months. Start a new discussion instead.