fflush() is not working in Linux - c

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;
}

Related

Why write() executes immediately, but printf() not? [duplicate]

#include <stdio.h>
#define MAXLEN 256
int main() {
int n;
char buf[MAXLEN];
while((n = read(0,buf,sizeof(buf))) != 0){
printf("n: %d:",n);
write(1,buf,n);
}
return 1;
}
The output of the program (where the first read and first write is typed by the user and echoed by the terminal) is:
read
read
write
write
n: 5:n: 6:
The output of printf comes after pressing Ctrl+D at the standard input and not along with the subsequent reads. Why does this happen?
Printf is buffered.
You can force printf to 'flush' its buffer using the fflush call:
#include <stdio.h>
#define MAXLEN 256
int main() {
int n;
char buf[MAXLEN];
while((n = read(0,buf,sizeof(buf))) != 0){
printf("n: %d:",n);
fflush(stdout); /* force it to go out */
write(1,buf,n);
}
return 1;
}
In general, printf() being buffered is a good thing. Unbuffered output, particularly to visible consoles that require screen updates and such, is slow. Slow enough that an application that is printf'ing a lot can be directly slowed down by it (especially on the Windows platform; Linux and unixes are typically impacted less).
However, printf() being buffered does bite you if you also fprintf(stderr,) - stderr is deliberately unbuffered. As a consequence, you may get your messages with some printf() missing; if you write to another FILE handle that is also associated with the terminal, and might be unbuffered, make sure you first explicitly fflush(stdout).
The manpage for fgets tells me:
It is not advisable to mix calls to input functions from the stdio
library with low-level calls to read(2) for the file descriptor associ‐
ated with the input stream; the results will be undefined and very
probably not what you want.
So the best solution would be not to to use write and printf on the same descriptor.
Printf is using stdio and it is buffered.
Push it out by sending a changing to "n: %d:\n"
You can use the std fflush() function to flush the std out buffer or you can make use of an additional \n at the end of the control string inside the printf. Something like this
printf("\n :%d:\n",n);
Its always better to use the write() & read() functions in C instead of printf() and scanf(). Printf and scanf have got some problems like printf stores the string parameter in stdout buffer. So a manual flush is required which is done through fflush function or by means of \n. In a small hello world printing program you will not find such a problem as the stdout buffer is flushed at the end of the program execution. Better use write() which works fine. scanf also have the problem of reading spaces and a lot of other problems related to stdin buffer.
For example in the code below:
main() { char a; int i=0,c; for(;i<2;i++) { scanf("%d",&c); scanf("%c",&a);} }
The above program as got the problem of reading \n into stdin on pressing enter. We could resolve this but not flushing the stdin buffer or making use of \n character. Always better to use the read() and write() functions.
Hope that helps....
Use fwrite (streams version) rather than write.
Note that, while is associated with file number 1, it isn't the same thing.

Program does not terminate or comes back with an error for scanf function

This program does not terminate nor does it let me input any values, simply a black screen with no output.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int size;
printf("Enter number of elements in array:");
scanf("%d", &size);
printf("\n%d\n", size);
return 0;
}
Sounds like you're suffering from buffering. Add
fflush(stdout);
after the printf line.
By default, if stdout goes to a terminal, it is line buffered, meaning output is only actually written when the buffer is full or when you output a newline (\n). Terminating the program (via exit() or returning from main) closes all open file handles and also forces a flush.
To make sure output is generated right then and there, call fflush.

nonblocking read from stdin

I expect ReadConsoleW() to return after reading a specific number of bytes.
But it doesn't return.
How can I make ReadConsoleW() return as soon as it finished reading the number of bytes specified?
The code I tried is here:
#include <stdio.h>
#include <Windows.h>
int main()
{
//something is being written to stdin.
Sleep(2000);
int b;
int r;
//read 3 wide character
ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), &b, 3*sizeof(TCHAR), (LPDWORD)&r, NULL);
//problem: no returns until enter pressed
putc(b,stdout);
while(1)
{};
}
Use SetConsoleMode to turn off ENABLE_LINE_INPUT flag. No line editing will be available, but it won't wait until the Enter is pressed.
Note that you can't read three WCHARs into an int.
Consider also asynchronous I/O in Windows using ReadFile/WriteFile.
See MSDN on asynchronous I/O
It is a little more complicated, but you do have what you want.

Strange Behaviour because of sleep()

I was just getting familiar with sleep(), i found that
#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
printf("%d",i);
sleep(1);
}
return 0;
}
this does not print number per iteration rather dumps all numbers when gets out of loop....
but when i modify printf...
#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
printf("%d\n",i);
sleep(1);
}
return 0;
}
and now as i've added '\n' new line it works as expected... why it is behaving strangely in former one...
This is because the output buffer isn't being flushed (in other words, actually committed to the terminal). When you write a newline, the output buffer is more likely to be (but still not always, in some cases) flushed. Many terminal implementations do this to improve performance. To force the behaviour you want, you need to call fflush(stdout); after each printf call, like this:
#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
printf("%d",i);
fflush(stdout);
sleep(1);
}
return 0;
}
What you are looking at is line buffered output. Actually writing to output is an expensive operation, so I/O streams are usually buffered. Actually writing the buffer is deferred until a specific event is encountered. In standard C, you have three types of buffering:
fully buffered - the buffer is written when full.
line buffered - the buffer is written when a newline is encountered (your case).
unbuffered - the buffer is written whenever an I/O function is executed. (Good for error logging.)
Writing the buffer is called flushing. That's why there is a stdio function called fflush(). You might also want to check out setvbuf() and its parameter constants, _IOFBF, _IOLBF and _IONBF. I am sure you can figure out what they mean without looking them up. ;-)
Edit: This program delivers as you originally expected:
#include <stdio.h>
// This is the header where sleep() is declared. Don't go without it.
#include <unistd.h>
int main()
{
int i=0;
// setvbuf() can be called on a stream only BEFORE
// you do any I/O on it!
setvbuf( stdout, NULL, _IONBF, 0 );
printf( "*********Testing Sleep***********\n" );
for ( i = 0; i < 10; ++i )
{
printf( "%d", i );
sleep( 1 );
}
return 0;
}
standard output for terminals is line buffered, output is not written unless there is a newline or you manually flush it.
Output is buffered, so that that the OS has an opportunity to optimize output speed. To make sure they are flushed immediately, do fflush (stdout);, but usually, you don't.
This is because printf() uses buffered output for better performance. Buffer is flushed to the console once \n is printed.
Printf is buffered.
You can force printf to 'flush' its buffer using the fflush call.
Or
Simply push the buffer to stdout using \n as in your case .
More detailed discussion is here

write() to stdout and printf output not interleaved?

#include <stdio.h>
#define MAXLEN 256
int main() {
int n;
char buf[MAXLEN];
while((n = read(0,buf,sizeof(buf))) != 0){
printf("n: %d:",n);
write(1,buf,n);
}
return 1;
}
The output of the program (where the first read and first write is typed by the user and echoed by the terminal) is:
read
read
write
write
n: 5:n: 6:
The output of printf comes after pressing Ctrl+D at the standard input and not along with the subsequent reads. Why does this happen?
Printf is buffered.
You can force printf to 'flush' its buffer using the fflush call:
#include <stdio.h>
#define MAXLEN 256
int main() {
int n;
char buf[MAXLEN];
while((n = read(0,buf,sizeof(buf))) != 0){
printf("n: %d:",n);
fflush(stdout); /* force it to go out */
write(1,buf,n);
}
return 1;
}
In general, printf() being buffered is a good thing. Unbuffered output, particularly to visible consoles that require screen updates and such, is slow. Slow enough that an application that is printf'ing a lot can be directly slowed down by it (especially on the Windows platform; Linux and unixes are typically impacted less).
However, printf() being buffered does bite you if you also fprintf(stderr,) - stderr is deliberately unbuffered. As a consequence, you may get your messages with some printf() missing; if you write to another FILE handle that is also associated with the terminal, and might be unbuffered, make sure you first explicitly fflush(stdout).
The manpage for fgets tells me:
It is not advisable to mix calls to input functions from the stdio
library with low-level calls to read(2) for the file descriptor associ‐
ated with the input stream; the results will be undefined and very
probably not what you want.
So the best solution would be not to to use write and printf on the same descriptor.
Printf is using stdio and it is buffered.
Push it out by sending a changing to "n: %d:\n"
You can use the std fflush() function to flush the std out buffer or you can make use of an additional \n at the end of the control string inside the printf. Something like this
printf("\n :%d:\n",n);
Its always better to use the write() & read() functions in C instead of printf() and scanf(). Printf and scanf have got some problems like printf stores the string parameter in stdout buffer. So a manual flush is required which is done through fflush function or by means of \n. In a small hello world printing program you will not find such a problem as the stdout buffer is flushed at the end of the program execution. Better use write() which works fine. scanf also have the problem of reading spaces and a lot of other problems related to stdin buffer.
For example in the code below:
main() { char a; int i=0,c; for(;i<2;i++) { scanf("%d",&c); scanf("%c",&a);} }
The above program as got the problem of reading \n into stdin on pressing enter. We could resolve this but not flushing the stdin buffer or making use of \n character. Always better to use the read() and write() functions.
Hope that helps....
Use fwrite (streams version) rather than write.
Note that, while is associated with file number 1, it isn't the same thing.

Resources