I am a newbie to buffered streams.I was write a simple c program which takes a string as a user input and displays it back.My working environment is eclipse under windows.The code is as follow:
#include<stdio.h>
enum { max_string = 127 };
static char string[max_string+1] = "";
void main(){
printf("type the input string---> \n");
fgets(string,max_string,stdin);
printf("the input string was ---> %s\n",string);
}
While running it,the user input is taken first and the two printf()'s are executed after.
The output sample is:
user input
type the input string--->
the input string was ---> user input
I tried the upper code in CodeBlocks IDE and it worked fine.The output is as follow:
type the input string--->
user input
the input string was ---> user input
What is the problem?
I also added a \n at the last of my printf() so as to flush them immediately.
Regards.
stdout is line-buffered only if connected to a terminal. Eclipse's terminal-emulation might not be detected as terminal.
From man stdout:
The stream stdout is line-buffered when it points to a terminal.
There are several way to get around this limitation:
call fflush(stdout) every time output shall appear
set stdout to be unbuffered by using setvbuf() like this
setvbuf(stdout, NULL, _IONBF, 0);
prior to using stdout.
use stderr which isn't buffered by default
OK!! after some googling i found out that the eclipse terminal emulator do more buffering than the normal terminal.We need to do fflush(stdout); after the printf to make it working.
Related
Terminal is not synchronized with the program.
This is my simple code to see if it works:
#include <stdio.h>
int main(void){
puts("Hello World!");
system("pause");
return 0;
}
but in the local terminal appears
Press a key to continue...
before
Hello World!
This means that it is not synchronized with the program. How can I solve?
The problem is probably that the output buffer is not getting flushed before the function system is executed.
In order to explicitly flush the output buffer, you can add the line
fflush( stdout );
immediately before the call to system.
On most platforms, the standard output stream is line-buffered, so it should not be necessary to flush the output buffer, because puts automatically adds a newline character to the string, which should cause a line-buffered stream to be automatically flushed. However, according to the information you provided, the standard output stream does not seem to be line-buffered in Eclipse. It seems to be fully-buffered instead.
#include <stdio.h>
int main(){
char a[2] = {0};
a[0] = 't';
printf("%s", a);
scanf("%c", a);
return 0;
}
scanf here will cause an automatic flush of stdout.
Running a.out will print t on the terminal before running scanf, more info: How is printf getting flushed before scanf is executed?
However, doing a.out > out.txt and terminating it with ^C does not print anything inside out.txt yet the output still appeared on the screen without redirecting stdout with >.
If stdout is being flushed then why out.txt is still empty?
If it's not being flushed then how did t appear on the screen in the first example?
(I know using \n or a manual fflush or properly terminating the program will fix the issue, i'm just curious about this behaviour).
The key is the word interactive:
The input and output dynamics of interactive devices shall take place as specified in 7.21.3.
As soon as you redirect the standard output to a file, it is no longer interactive.
For example the Linux C standard library actually executes the analogue of the isatty library call to figure this out. If it figures out that standard output is not directed to file it will also break this relationship. It will also increase the I/O performance of programs that work as part of a command pipeline.
You can yourself test whether stdout is connected to a terminal by executing
#include <unistd.h>
printf("stdout is connected to a terminal: %d\n", isatty(fileno(stdout)));
This question already has answers here:
What are the rules of automatic stdout buffer flushing in C?
(5 answers)
Is stdout line buffered, unbuffered or indeterminate by default?
(1 answer)
Closed 3 years ago.
I have read many questions with people asking why printf did not work before a while loop; the answer was that it was not flushing stdout because they did not have a new line character in their format string. However, the following simple code is still not producing output for me:
#include <stdio.h>
int main() {
printf("Hello world!\n");
while (1);
return 0;
}
However, adding fflush(stdout); after the printf call produces output. The new line character is supposed to make this unnecessary, so why does it not work without it?
It's quite common for stdout to be line-buffered when connected to a terminal (flushed on line feed), and block-buffered otherwise (flushed when buffer is full).
For example,
#include <stdio.h>
#include <unistd.h>
int main(void) {
printf("foo\n");
sleep(5);
return 0;
}
Test:
$ ./a
foo
[5s pause]
$ ./a | cat
[5s pause]
foo
(gcc on Linux)
I'm using mingw with Eclipse on Windows.
It seems that Eclipse is connecting the stdout of your program to a pipe so it can collect the output and display it in its window. Your program thus uses block buffering for stdout.
A very good answer by #schot here.
He said :
The C99 standard does not specify if the three standard streams are unbuffered or line buffered: It is up to the implementation. All UNIX implementations I know have a line buffered stdin. On Linux, stdout is line buffered and stderr unbuffered.
One way to be sure that your line(s) will be printed directly is making stdout unbuffered:
setbuf(stdout, NULL);
/* or */
setvbuf(stdout, NULL, _IONBF, 0);
But you can only do this once, and it must be before you write to stdout or perform any other operantion on it. (C99 7.19.5.5 2)
Additional Info :
Shouldn't a new line character flush the output?
-It depends, if the output device is determined to be interactive (e.g. a terminal) the newline flush the buffer. Otherwise new line(s) don't flush the buffer.
What constitutes an interactive device is implementation-defined (C99 section 5.1.2.3/6)
I have started looking into command processing with C but I have hit a problem with this C program. It is executing the ls command before it is intended.
Gcc info:
gcc version 6.2.1 20161124 (Debian 6.2.1-5)
This is the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
printf("Is command processor available?\n");
if (system(NULL))
{
printf("Command processor available!\n");
}
else
{
printf("Command processor not available!\n");
exit(1);
}
printf("Executing command ls");
i=system("ls");
printf("Returned value is: %d.\n",i);
return 0;
}
The piece of code I am speaking about is this specific line:
printf("Executing command: ls");
If the program is ran with that piece of code the output is:
Is command processor available?
Command processor is available
systemProcessing systemProcessing.c
Executing command: lsReturned value is: 0.
It executes the command before actually being told to
But when I finish the code off with a new line '\n', its output is as expected:
Is command processor available?
Command processor is available
Executing command: ls
systemProcessing systemProcessing.c
Returned value is: 0.
Why is it that with the newline added to the string the code prints what it is about to do before executing, but without it it executes and then prints that is is going to execute?
It's a buffering issue. You need to do:
printf("Executing command ls");
fflush(stdout); //<<
i=system("ls");
or, if your output is a line-buffered terminal and you're OK
with adding a line instead of an explicit fflush(stdout) call:
printf("Executing command ls\n");
stdio 101:
Small read/writes to the OS are inefficient, so stdio IO (by default) associates each file handle/descriptor with an input buffer and an output buffer. stdio output calls output into the appropriate FILE's (in this case, it's stdout) output buffer (by memcpying the string), and only when the (large) buffer is full will a system call to write the whole buffer be made (problem solved).
An explicit flush of an output buffer may be elicited with the fflush() function. Additionally, if stdio detects an output FILE is a terminal, it will use line buffering which means it will call fflush() whenever it encounters a newline in the output.
The buffering mode of an stdio FILE may also be explicitly manipulated with the setvbuf() function. See the manpage in the link to learn how it can be used.
Standard output via printf is buffered, which means it doesn't flush to destination immediately after calling printf. When you use system to run a separate process after calling printf without that being flushed that new process's output might print before your printf gets printed.
Adding a new line makes the difference since a new line is immediately flushing the buffer. You could have used fflush too instead of newline.
This question already has answers here:
Why doesn't getchar() wait for me to press enter after scanf()?
(10 answers)
Closed 3 years ago.
I'm learning programmation in C and tried to create a program that asks the user his age. When the user writes his age (for example 18) he gets the message "So you're 18 years old". When I execute the .exe file it automatically closes after you see the message, so fast that you don't see it. Then I added getchar so that the user reads the message and then presses Enter to quite. Here's the program I wrote:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int age=0;
printf("How old are you?\n");
scanf("%d",&age);
printf("So you're %d years old", age);
getchar();
return 0;
}
Unfortunately, when I execute the .exe file, it still closes automatically like if the getchar() doesn't exist and I don't know why.
scanf("%d",&age);
When the execution of the program reaches the above line,you type an integer and press enter.
The integer is taken up by scanf and the \n( newline character or Enter )which you have pressed remains in the stdin which is taken up by the getchar().To get rid of it,replace your scanf with
scanf("%d%*c",&age);
The %*c tells scanf to scan a character and then discard it.In your case,%*c reads the newline character and discards it.
Another way would be to flush the stdin by using the following after the scanf in your code:
while ( (c = getchar()) != '\n' && c != EOF );
Note that c is an int in the above line
You're only having trouble seeing the result because you're starting the program from a windowing environment, and the window closes as soon as its internal tasks are completed. If you run the compiled program from a command line in a pre-existing shell window (Linux, Mac, or Windows), the results will stay on the screen after you're returned to the prompt (unless you've ended by executing a clear-screen of some sort). Even better, in that case, you don't need the extraneous getchar() call.
For Windows, after opening the command prompt window, you'd issue a "cd" command to change to the directory that contains the compiled program, and then type its name. For Linux (and, I presume, Mac, since Mac is UNIX under the hood), you'd need to type ./ ahead of the program name after changing to the appropriate directory with "cd".