2

I'm trying to write a program that reads various user inputs. These string inputs can contain or not whitespace. I made a version that works good, but needs a while loop (inside clearStdin function) as show below:

#include <stdio.h> #include <stdlib.h> void clearStdin(void); int main(void) { char name1[8], name2[5]; printf("Write a name: "); fgets(name1, sizeof name1, stdin); clearStdin(); printf("Write another name: "); fgets(name2, sizeof name2, stdin); clearStdin(); printf("First name is: %s\n", name1); printf("Second name is: %s\n", name2); return 0; } void clearStdin(void){ int c; while(( c = getchar() ) != '\n' && ( c != EOF )); } 

I tried to use

scanf("%7[^\n]", name1); scanf("%*[^\n]"); scanf("%*c"); 

and also other ways. My question is: There is other ways for the program to work without using the while (or another) loop? Any scanf or fgets way only?

Exemple input:

 Write a name: RafaelBluhm Write another name: Tainah Julião 

Required output:

First name is: RafaelB Second name is: Tain 

Fails outputs (Other ways):

First name is:Tain Second name is:@� 
5
  • is it possible that you did not use \0 to close your string? Commented Jan 20, 2015 at 22:34
  • 2
    BTW char c; at clearStdin() : should be int c; Commented Jan 20, 2015 at 22:34
  • always check the returned value from each call to 'fgets; and/ or 'scanf' to assure the operation was successful. always place a leading ' ' (space) in the format string of scanf() so it will skip over any leading white space. always place a limit/max length on when using %s in scanf() so no buffer overrun will occur. suggest using fscanf() rather than scanf() Finally, I suggest input whole line with fgets(), the use sscanf() to extract first/last name. and always clear each first/last name buffer to '\0' before using sscanf() so when no last name, nothing is printed. Commented Jan 21, 2015 at 2:18
  • 1
    scanf("%8[^\n]", name1); should be scanf("%7[^\n]", name1); Commented Jan 21, 2015 at 2:23
  • OT: It's more common (and will cause less trouble with buffering) to use stderr for a prompt: fputs("Write a name: ", stderr) or fprintf(stderr, "Write a name: "); Commented Jan 21, 2015 at 10:11

3 Answers 3

3

For general implementation: No, there is no other way to clear the input buffer.

For a given specific environment, there might be an environment-specific way. For example, on Linux/Unix, there is a way to see how many terminal buffer characters are pending through ioctl() and another way to clear them.

Sign up to request clarification or add additional context in comments.

2 Comments

This is correct. More detail at stackoverflow.com/questions/22901901/… - however, on Linux (and, apparently, DOS), fflush(stdin) does actually work - see the man page.
Even if it was reliable, it would still be terrible. Imagine if stdin came from a pipe or redirected file (which is a great thing to do; everyone hates typing repeated stuff just for the sake of testing)!
2

If you want to use scanf, you can use

scanf("%*[^\n]%*1[\n]"); 

This is equivalent to your clearStdin function.

I'd suggest that you indicate EOF by the return value (scanf returns EOF on end-of-file or error here), and check for that -- a program shouldn't attempt to read further input after the first end-of-file.

3 Comments

Works good. But only to clear fgets imput. I tried to use with scanf and it did not work. I heard that is not good to mix this two functions.
@RafaelBluhm, iIt's not necessarily bad to mix them (actually, it's bad to use either of them (some scanf calls are OK), but that's another discussion), you must keep in mind that they work differently. This scanf call should do exactly the same as the clearStdin function. With what scanf call doesn't this work? And btw, you probably want to check if fgets has read a newline (strchr) or not (and only clear stdin if it hasn't).
@ mafso scanf("%*[^\n]%*c"); works well too. Ty for the sugests.
-1

I think you can use fflush(stdin); I have use it before but I'm not sure if its stantard C , test it and let me know.

5 Comments

fflush(stdin); donts works. It's not in standard C. The rest of buffter stored in the first string is placed in the second
Please, let's abolish [this abomination[(stackoverflow.com/questions/2979209/using-fflushstdin) from the face of the earth!
Whilst it's not POSIX compliant, it does work under Linux (and allegedly DoS) - see link on other post. The answerer did say he wasn't sure it was standard C so let's not be too harsh.
Even if it was standard, it would still be terrible. The OP's loop will consume up to and including the next newline; if fflush(stdin) where to reliably work, it would just throw away the rest of the buffer. Now imagine if stdin doesn't come from a human typing in a terminal, but from a pipe or a redirected file.
This solution is to solve THIS problem... in this case that's how you get the input.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.