Emacs`hell`和`eshell`输入/输出

时间:2015-09-03 16:02:05

标签: shell emacs

当我在Windows上的Emacs中使用shelleshell时,我的C程序输出有问题,如果它们中有scanf。比如这个程序 编译后工作正常

#include <stdio.h>

int main()
{
    printf("Hello, world!");
    return 0;
}

如果我从shelleshell运行它,则打印如下:

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%无济于事。

1 个答案:

答案 0 :(得分:1)

当emacs运行时,shell进程中的外部命令位于管道的末尾。由于这个原因,输出针对吞吐量而不是终端进行了优化,这意味着输出以块的形式缓冲。我怀疑这就是你所看到的。

C99标准

此缓冲是C99标准的一部分,参见§7.19.3/ 7

  

在程序启动时,预定义了三个文本流,不需要   明确打开 - 标准输入(用于读取传统输入),   标准输出(用于写入常规输出)和标准错误   (用于编写诊断输出)。最初打开时,标准   错误流未完全缓冲;标准输入和标准   当且仅当流可以时,输出流才完全缓冲   决定不参考互动设备。

GNU的建议

emacs W32 FAQ对于在这种情况下应该做些什么有一些建议:

W32 FAQ: Buffering in Shells

禁用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的命令。

相关问题