C printf not working as expected from terminal

chessprogrammer :

I've reduced the problem as much as I could to the following minimal code snippets. If more info is needed please ask.

Lets say I have a Java class called A whose main method is this:

public static void main (String args[])throws Exception{
    Process p = new ProcessBuilder(args).redirectErrorStream(true).start();
    Scanner in = new Scanner(new InputStreamReader(p.getInputStream())); 
    System.out.println(in.nextLine());
}

Basically, it runs a program from the terminal, reads in a line from that program, and echos it. Very simple.

Now I have a second program written in c++ like this:

int main() 
{
    string s;
    cout << "example2 in c++"<<endl;;
    cin >> s;
    return 0;
}

When I invoke:

java A pathToC++Program

the program runs as expected, outputting the string sent from the cpp program and terminating.

I have an equivalent program in c:

int main()
{
   char s[10];
   printf("example1 in c\n");
   fgets(s,10,stdin); 
   return 0;
}

When I invoke:

java A pathToCprogram

the program halts, and nothing is printed out.

When I remove the fgets line from the c program so that it looks like this:

int main()
{
   printf("example1 in c\n");
   return 0;
}

then the Java program is able to recognize the line and print it out. Thus it would seem that fgets is the problematic line, yet when fgets was included, even the line before it didn't work.

What is going on here?

(I have no idea if this is a peculiarity of Java or C, so I included both tags.)

Some programmer dude :

Writing to stdout (which is where printf will write its output) is by default line-buffered, meaning the buffer will be flushed on newline.

But that's the default when running directly from a terminal. If the output is not a terminal, then stdout will be fully buffered, meaning it will only be flushed when you fill the buffer. Or to an explicit fflush(stdout) call.

In your C++ program you do flush the output explicitly, by using std::endl (it writes a newline and flushes the buffered output). In your C program there's no such flushing of the output buffer.

This is really very platform specific, but for POSIX platforms (like Linux or macOS) it's like described above. I think it's quite similar for Windows.

As for why it works when you remove the fgets statement, it's probably because fgets will block execution until end-of-file or some (newline-terminated) input have been read. Without the fgets the program will exit immediately after printf and that will lead to the stdout buffer being flushed.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=111043&siteId=1