当我在Windows上的Emacs中使用shell
和eshell
时,我的C程序输出有问题,如果它们中有scanf
。比如这个程序
编译后工作正常
#include <stdio.h>
int main()
{
printf("Hello, world!");
return 0;
}
如果我从shell
或eshell
运行它,则打印如下:
c:\Users\xxx>a.exe
a.exe
Hello, world!
但是这个程序并没有按预期工作
#include <stdio.h>
int main()
{
int a;
printf("Hello, world!\nEnter number:");
scanf("%d", &a);
return 0;
}
当我在shell
中运行它时会打印
c:\Users\xxx>a.exe
a.exe
然后它被卡住了。如果我输入123
然后Enter
,则输入
123 <= this is what I entered
Hello, world!
Enter number:
看起来像一些奇怪的缓冲行为。当我检查echo %SHELL%
缓冲区中的shell
时,它会打印
C:/App/emacs/libexec/emacs/24.5/i686-pc-mingw32/cmdproxy.exe
我需要做些什么才能修复shell
的行为并让它按照通常的预期运行?将SHELL
变量更改为%ComSpec%
无济于事。
答案 0 :(得分:1)
当emacs运行时,shell进程中的外部命令位于管道的末尾。由于这个原因,输出针对吞吐量而不是终端进行了优化,这意味着输出以块的形式缓冲。我怀疑这就是你所看到的。
C99标准
此缓冲是C99标准的一部分,参见§7.19.3/ 7
在程序启动时,预定义了三个文本流,不需要 明确打开 - 标准输入(用于读取传统输入), 标准输出(用于写入常规输出)和标准错误 (用于编写诊断输出)。最初打开时,标准 错误流未完全缓冲;标准输入和标准 当且仅当流可以时,输出流才完全缓冲 决定不参考互动设备。
GNU的建议
emacs W32 FAQ对于在这种情况下应该做些什么有一些建议:
禁用C
的缓冲正如本文所述,程序通常可以获得两全其美的一种方式:即允许emacs运行但在管道上获得更高性能是使用TERM变量来指示程序在emacs中运行。所以这就像是:
char *term = getenv("TERM");
if (term != NULL && !strcmp(term,"emacs")==0) {
setvbuf(stdout, NULL, _IONBF, 0);
}
就像一个例子。 stdio库的不同缓冲模式列在setvbuf的页面上。
std:cout和C ++
iostream和libc之间的关系,以及它们是否同步更复杂一些。但是我怀疑你在写endl
时使用了std::cout
,其中包括同花顺。 <{1}}默认情况下是无缓冲的。
类Unix环境下的解决方案
在具有pty的Unix环境中,可以设置与伪终端通信的进程。 expect工具包有一个名为std::cerr
的命令。