while((c = getchar()) != '\n' && c != EOF);
This reads input characters until it reaches either the end of the line (i.e., getchar() returned '\n) or end-of-file or an error condition (i.e., getchar() returned EOF).
If stdin is reading from the keyboard, it discards input until you press Enter.
Leaving off the EOF check could give you an infinite loop if there's an input error, or if you trigger an end-of-file condition (on Unix, by typing Ctrl-D twice).
This could be useful, for example, after using scanf() to read an integer. If you execute scanf("%d", &num); and type 123, it will read those 3 digits (and store the value 123 in n), but leave everything after that waiting to be read. The above line can be used to skip the rest of the input line.
(An alternative, likely a better one, is to read whole lines using fgets() and parse them using sscanf().)
This is not equivalent to fflush(stdin). A far as the C standard is concerned, calling fflush on an input stream has undefined behavior.
Some implementations do define the behavior of fflush(stdin). On systems that use GNU libc, for example (most Linux system):
For input streams,
fflush()discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.
That's not the same as discarding input up to the end of the line. And using it makes your code non-portable.
Answer from Keith Thompson on Stack Overflowwhile((c = getchar()) != '\n' && c != EOF);
This reads input characters until it reaches either the end of the line (i.e., getchar() returned '\n) or end-of-file or an error condition (i.e., getchar() returned EOF).
If stdin is reading from the keyboard, it discards input until you press Enter.
Leaving off the EOF check could give you an infinite loop if there's an input error, or if you trigger an end-of-file condition (on Unix, by typing Ctrl-D twice).
This could be useful, for example, after using scanf() to read an integer. If you execute scanf("%d", &num); and type 123, it will read those 3 digits (and store the value 123 in n), but leave everything after that waiting to be read. The above line can be used to skip the rest of the input line.
(An alternative, likely a better one, is to read whole lines using fgets() and parse them using sscanf().)
This is not equivalent to fflush(stdin). A far as the C standard is concerned, calling fflush on an input stream has undefined behavior.
Some implementations do define the behavior of fflush(stdin). On systems that use GNU libc, for example (most Linux system):
For input streams,
fflush()discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.
That's not the same as discarding input up to the end of the line. And using it makes your code non-portable.
This code, assuming the file (or some other input) has been opened, will continue to get character by character until it finds a newline (\n) or an end of file (eof).
fflush will just clear the stream for an open file.
c++ - Alternative for fflush(stdin)? - Stack Overflow
[C] Can someone please explain fflush(stdin) to me?
What's equivalent of fflush( stin ) in C - C++ Forum
c - Replacement of fflush(stdin) - Stack Overflow
Videos
The call to fflush(stdin) is undefined behavior in C (and, consequetly, in C++).
The C language standard, ISO 9899:1999 states in 7.19.5.2/2
If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined
To discard the entire input up to the next end of line, in C++, the most robust approach is
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
As for the program "flashing and going away", are you perhaps executing a console application on a Windows platform? Such applications are best executed from a console window (Start->run->cmd.exe)
Use cin.get () instead of getchar () and you should be fine. The problem is that C++ I/O streams and C I/O functions are working on top of the same file descriptors, but have different buffers. I can't tell what exactly is going on w/o debugging, but it feels like getchar() that you are calling to pause a program until character is entered is getting characters that were already read by C++ input stream. So it gets data and unblocks, so you exit the program.
If you still have the problem, make sure you don't enter `\n' characters (i.e. don't press enter). Because pressing enter after input is actually a character that you can read. This problem is usually solved with peeking (see http://www.cplusplus.com/reference/iostream/istream/peek/).
I understand that this command flushes out the input stream but what does it mean by "flushing the stream".
This is well explained in the C FAQ. See also: explanation. The proposed solutions:
- Quit using scanf. Use
fgetsand thesscanf Use this to eat the newline
while((c = getchar()) != '\n' && c != EOF) /* discard the character */;
The fact that flushing stdin works on some implementations is wrong.
Some vendors do implement fflush so that fflush(stdin) discards unread characters, although portable programs cannot depend on this.
scanf(" %c",&c);
or
scanf(" ");
//reading operation (gets(), fgets(stdin,...) etc)
Spaces in the scanf() format string will ignore any whitespace until the first non-whitespace.
One possibility is to consume the newline left by the scanf via using something like getchar():
printf("Gimme number");
scanf("%d",&number);
getchar();
printf("Gimme string");
gets(string);
Another possibility is to just use scanf's:
printf("Gimme number");
scanf("%d",&number);
printf("Gimme string");
scanf(" %99s", string);
Where you'd replace the 99 by whatever length your string buffer is, note the space before the % to make sure it ignores white space (or tabs or newlines) left on stdin.
Read full lines from the input (lines containing the ENTER).
The parse the lines (possibly with strtol(), srttod(), or sscanf()).
char buffer[1000];
int number;
printf("Gimme number: ");
fflush(stdout);
fgets(buffer, sizeof buffer, stdin); // needs error checking
number = strtol(buffer, &err, 10); // needs error checking
printf("Gimme string: ");
fflush(stdout);
fgets(buffer, sizeof buffer, stdin); // needs error checking
strcpy(string, buffer);
string[strlen(string) - 1] = 0; // remove ENTER
fflush only flush output streams.
If you want to flush stdin, keep reading until you get EOF, something like:
int i;
while (((i = getchar()) != '\n') && (i != EOF));
You can use fgets() instead of gets(): https://stackoverflow.com/a/4309760/1758762
As everyone else said, the canonical alternative to gets() is fgets() specifying stdin as the file stream.
char buffer[BUFSIZ];
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
...process line of data...
}
What no-one else yet mentioned is that gets() does not include the newline but fgets() does. So, you might need to use a wrapper around fgets() that deletes the newline:
char *fgets_wrapper(char *buffer, size_t buflen, FILE *fp)
{
if (fgets(buffer, buflen, fp) != 0)
{
size_t len = strlen(buffer);
if (len > 0 && buffer[len-1] == '\n')
buffer[len-1] = '\0';
return buffer;
}
return 0;
}