i have some code that run repetedly :
printf("do you want to continue? Y/N: \n");
keepplaying = getchar();
in the next my code is running it doesnt wait for input.
i found out that getchar in the seconed time use '\n' as the charcter.
im gussing this is due to some buffer the sdio has, so it save the last input which was "Y\n" or "N\n".
my Q is, how do i flush the buffer before using the getchar, which will make getchar wait for my answer?
Flushing an input stream causes undefined behaviour.
int fflush(FILE *ostream);
ostream 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 properly flush the input stream do something like the following:
int main(void)
{
int ch;
char buf[BUFSIZ];
puts("Flushing input");
while ((ch = getchar()) != '\n' && ch != EOF);
printf ("Enter some text: ");
if (fgets(buf, sizeof(buf), stdin))
{
printf ("You entered: %s", buf);
}
return 0;
}
See Why fflush(stdin) is wrong and Flush the input buffer.
use fflush() and flushall() before printf
As far as I know, flushall is not POSIX. In order to flush a console buffer in a standard way, you can simply use the command:
fflush(NULL);
This topic seems to be a bit old but I hope this can still help the others.
Related
If I were to print a prompt to stdout:
printf("> ");
and then I said
fgets(tester, 80, stdin);
would fgets read the whole line including the "> " or would it start after that?
The prompt is output (on stdout). fgets is reading input from stdin. So no, it won't read your prompt.
Your terminal displays stdout, stderr and stdin all together, but that doesn't mean there isn't an underlying distinction between them.
stdout is typically line buffered, and printf("> "); lacks a new line, so the output may not appear on a terminal display until later. fflush(stdout) to insure it is outputted before the fgets().
printf("> ");
fflush(stdout);
fgets(tester, 80, stdin);
The fgets won't read anything because the printf will write on STDOUT and not on STDIN.
No. printf will reflect the stdout. It will never effects your stdin. The str buffer will reflect all the characters you give as an input after >.
Test for the same can be done like this:
#include<stdio.h>
int main() {
char str[80];
printf(">");
if( fgets (str, 60, stdin)!=NULL )
{
puts(str);
}
return 0;
}
I'm programming this code (personal software) for a spa which is still in a beta version but I encounter a issue well is more like an idea than an issues let me explain you:
Source code:
fflush(stdin);
gets(NC1.Customer_Nameandlastname);
fflush(stdin);
printf("provide the customer's age\n\t");
fflush(stdin);
scanf("%d",&NC1.Customer_Age);
fflush(stdin);
this is just part of the source code but what I want to do when the program is running is this:
If the the person that is typing the information makes a mistake or wants to retype the same information but the next command line is already waiting for the input data the question is how would I do to go back to the previous line and then after I finish continue to the next line?
So it is like how would I return to the previous scanf() if I already type that information and then the system is waiting for the next line.
Please help me because I dont really know what yo do I am seeking how to do it but I still not able to find it.
You cannot portably flush input from stdin with fflush(stdin);. It invokes undefined behavior.
You can read the rest of an offending line from stdin with this function:
void flush_line(FILE *fp) {
int c;
while ((c = getc(fp)) != EOF && c != '\n')
continue;
}
Furthermore, do not use gets(). This unsafe function (you cannot provide the size of the destination array, so any properly crafted input may cause undefined behavior, a flaw that can be used by an attacker to compromise your program). The function was finally removed from the C Standard in 2011. Use fgets() and remove the trailing linefeed if any this way:
if (fgets(line, sizeof line, stdin)) {
line[strcspn(line, "\n")] = '\0';
...
}
You cannot restart a failed scanf(). The return value gives you some information as to where it failed, but not enough to restart the parse reliably. A better way to parse standard input is to read line by line and use sscanf() to parse the lines. Example:
/* read the customer's age. Keep prompting in case of invalid input */
for (;;) {
char line[80];
printf("provide the customer's age\n\t");
/* force flush of stdout for systems that do not do it
automatically upon reading from stdin */
fflush(stdout);
if (!fgets(line, sizeof line, stdin)) {
/* end of file reached */
return -1;
}
if (sscanf(line, "%d", &NC1.Customer_Age) == 1) {
/* input parsed correctly, break out to the next question */
break;
}
/* parse failed, output an appropriate message and restart */
printf("bad input, please type a number\n");
}
This is really a basic problem, what you want is a loop like this
while (fgets(buffer, SIZE_OF_BUFFER, stdin) != NULL) {
if (is_input_valid(buffer) == 1)
break;
/* Or else, go again */
}
After asking the user for all the details, ask something like
Do you want to store this record in the database?
Instruct the user that if he makes a mistake, he should enter garbage for the following fields, and answer "no, I want to discard this record".
Maybe the user will understand by himself that this is what he should do, because asking for such confirmation is a pretty standard practice.
I used the fflush() in Linux GCC but it did not work. Are there any alternatives for that function? Here is my code:
#include<stdio.h>
void main()
{
char ch='y';
while(ch=='y')
{
int a;
printf("Enter some value:");
scanf("%d",&a);
fflush(stdin);
printf("Do you want to continue?");
scanf("%c",&ch)
}
The output that I got is:
Enter some value: 10
Then the program ends. That's all. What can I do in Linux? Is there an alternative function?
Don't use fflush, use this function instead:
#include <stdio.h>
void clean_stdin(void)
{
int c;
do {
c = getchar();
} while (c != '\n' && c != EOF);
}
fflush(stdin) depends of the implementation, but this function always works. In C, it is considered bad practice to use fflush(stdin).
One that always works on Linux:
#include <termios.h>
#include <unistd.h>
void clean_stdin()
{
int stdin_copy = dup(STDIN_FILENO);
/* remove garbage from stdin */
tcdrain(stdin_copy);
tcflush(stdin_copy, TCIFLUSH);
close(stdin_copy);
}
You can use tcdrain and tcflush not only for in/out/err fd.
The behavior of fflush is not defined for input streams (online 2011 standard):
7.21.5.2 The fflush function
Synopsis
1
#include <stdio.h>
int fflush(FILE *stream);
Description
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.
3 If stream is a null pointer, the fflush function performs this flushing action on all
streams for which the behavior is defined above.
Returns
4
The fflush function sets the error indicator for the stream and returns EOF if a write
error occurs, otherwise it returns zero.
I faced the same problem while working on LINUX and an alternative solution of this problem can be that you define a dummy character lets say char dummy;
and put a scanf() to scan it just before your actual input takes place. This worked for me. I hope it would work for you too.
fflush() doesn't do much for input streams but since scanf() never returns this doesn't matter. scanf() blocks because the terminal window doesn't send anything to the C program until you press Enter
You have two options:
Type 10 Enter
Put the terminal into raw mode.
The second option has many drawbacls like you will lose editing capabilities, so I suggest to read the input line by line.
You must include and use __fpurge(whatever you want) instead.
Salute from argentina
Use getchar() instead, after scanf
#include<stdio.h>
int main()
{
char ans='y';
int a;
while(ans=='y'||ans=='Y')
{
printf("Type a number:-");
scanf("%d",&a);
printf("square of number = %d\nwant to enter
number again(y/n)?\nANS=",a*a);
scanf("%s",&ans);//use %s in place of %c
}
return 0;
}
By using bzero(); system call in Linux we can flush the previous stored value.
Please read the manual page of bzero(); by typing in terminal man bzero.
try this example
#include<stdio.h>
#include<string.h>
int main()
{
char buf[]={'y'};
int num;
while(buf[0]=='y')
{
printf("enter number");
scanf("%d",&num);
printf("square of %d is %d\n",num,num*num);
bzero(buf, 1);
printf("want to enter y/n");
scanf("%s",&buf[0]);
}
return 0;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Using fseek with a file pointer that points to stdin
i have a program that use fseek to clear my input buffer, it works well in Windows, buf fails in Linux. Please help me .
#include <stdio.h>
#define NO_USE_FSEEK 0
int main(int argc, char *argv[])
{
char ch = 'a';
int i = 1;
long int fpos = -1;
while(1)
{
printf("loop : %d\n", i);
fseek(stdin, 0L, SEEK_END); /*works in Windows with MinGW, fails in Linux*/
fpos = ftell(stdin);
if (-1 == fpos)
{
perror("ftell failure:"); /*perror tells it is Illegal Seek*/
printf("\n");
}
else
{
printf("positon indicator:%ld\n", fpos);
}
scanf("%c", &ch);
printf("%d : %c\n", (int)ch, ch);
i++;
}
return 0;
}
Thanks in advance!
This is not the accepted way to "clear your input buffer" on either Windows or Linux.
On windows, using the MSVCRT version of the standard C functions, there is an extension allowing fflush(stdin) for this purpose. Note that on other systems this is undefined behavior.
Linux has a function called fpurge with the same purpose.
However, I have to ask, why do you want to clear your input buffer? If it's the usual complaint people have with scanf not reading to the end of the line, it would be better to write code to actually read and discard the rest of the line (loop with getc until reading a '\n', for example, as in pmg's answer). Clearing the input buffer will tend to skip a large amount of data when used on a redirected file or pipe rather than the normal console/tty input.
i guess fseek will not work with stdin. Because the size of stdin is not known.
Test the return value from fseek() (in fact, test the return value from all <stdio.h> input functions).
if (fseek(stdin, 0, SEEK_END) < 0) { perror("fseek"); exit(EXIT_FAILURE); }
Use the idiom
while ((ch = getchar()) != '\n' && ch != EOF) /* void */;
/* if (ch == EOF)
** call feof(stdin) or ferror(stdin) if needed; */
to ignore all characters in the input buffer up to the next ENTER (or end of file or input error).
I have 2 fgets into my code and both of them aren't wait for input...
This is an example of the first fgets...
printf("Insert path: ");
if(fgets(dirpath, BUFFGETS, stdin) == NULL){
perror("fgets dir path");
close(sockd);
}
and, as i've written before, also the next fgets is not waiting for my input :(
Before the first fgets i have 2 scanf("%ms", &string); (if this could be the trouble).
i think scanf does not read in the linebreak. You can try to read it in first with an additional fgets after scanf().