che*_*mer 2 c c++ java terminal command-line
我尽可能地将问题减少到以下最小的代码片段.如果需要更多信息,请询问.
假设我有一个名为A的Java类,其主要方法是:
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());
}
Run Code Online (Sandbox Code Playgroud)
基本上,它从终端运行一个程序,从该程序读取一行,并回显它.非常简单.
现在我有第二个用c ++编写的程序,如下所示:
int main()
{
string s;
cout << "example2 in c++"<<endl;;
cin >> s;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我调用时:
java A pathToC++Program
Run Code Online (Sandbox Code Playgroud)
程序按预期运行,输出从cpp程序发送的字符串并终止.
我在c中有一个等效的程序:
int main()
{
char s[10];
printf("example1 in c\n");
fgets(s,10,stdin);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我调用时:
java A pathToCprogram
Run Code Online (Sandbox Code Playgroud)
程序停止,没有打印出来.
当我从c程序中删除fgets行时,它看起来像这样:
int main()
{
printf("example1 in c\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后Java程序能够识别该行并将其打印出来.因此,似乎fgets是有问题的线,但是当包含fgets时,即使它之前的线也不起作用.
这里发生了什么?
(我不知道这是Java还是C的特性,所以我包含了两个标签.)
写入stdout(其中printf将写入其输出的位置)默认为行缓冲,这意味着缓冲区将在换行符上刷新.
但这是直接从终端运行时的默认设置.如果输出不是终端,stdout则将完全缓冲,这意味着只有在填充缓冲区时才会刷新.或者是明确的fflush(stdout)电话.
在您的C++程序中,您可以使用std::endl(它写入换行符并刷新缓冲的输出)显式刷新输出.在你的C程序中,没有这样的输出缓冲区刷新.
这是非常特定于平台的,但对于POSIX平台(如Linux或macOS),它就像上面描述的那样.我觉得它与Windows非常相似.
至于为什么它在删除fgets语句时有效,可能是因为它fgets会阻止执行,直到读取文件结尾或某些(换行符已终止)输入为止.没有fgets程序将立即退出printf,这将导致stdout缓冲区被刷新.