954,499 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

scanf() and fgets() problems.

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.

coril
Newbie Poster
7 posts since Dec 2010
Reputation Points: 10
Solved Threads: 0
 

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.

coril
Newbie Poster
7 posts since Dec 2010
Reputation Points: 10
Solved Threads: 0
 

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.

WaltP
Posting Sage w/ dash of thyme
Moderator
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

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.

Adak
Nearly a Posting Virtuoso
1,479 posts since Jun 2008
Reputation Points: 425
Solved Threads: 185
 
fflush() on any input stream, like stdin, is deprecated,


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

WaltP
Posting Sage w/ dash of thyme
Moderator
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

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.

coril
Newbie Poster
7 posts since Dec 2010
Reputation Points: 10
Solved Threads: 0
 
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.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: