我已获得以下代码:
std::cerr << "Hello" << std::endl;
std::cerr << "World" << std::endl;
......通常会很棒。
但是:我在Erlang端口程序中运行它,并且Erlang已经对终端做了一些事情,这意味着&#34; \ n&#34;不再转换为CRLF,这意味着我的输出显示为......
Hello
World
Erlang对我的终端做了什么?我该如何检测到它?在这种情况下,如何让std::endl
输出\r\n
?
注意:它(可能)不仅仅是Erlang从我的程序中摄取stderr并搞砸了换行符。如果我使用普通的&#39;在NIF中printf("Hello\n")
,我看到同样的问题。
答案 0 :(得分:2)
首先不要使用::std::endl
。它并没有真正做你想要的。它始终输出'\n'
并刷新流。在大多数情况下,刷新流是一个巨大且不必要的性能。
而'\n'
我的意思就是这样。实际的文字'\n'
。它不做任何类型的翻译或人们认为它做的任何事情。即使在Windows上,也只是一个平坦的'\n'
和同花。您在Windows下获得的换行符由较低级iostream
工具处理,并受流是否处于binary
模式控制。
Erlang对您的终端做了什么可能是将其置于CBREAK模式。这里有一个很好的问题,有一些答案描述了Unix中raw,cooked和cbreak终端驱动程序模式之间的差异。
您可以手动将终端设置回熟化模式。 Erlang这样做的唯一原因是,通常你只能得到人们输入时键入的内容。 CBREAK可让您输入所有字符。
你也可以测试自己终端所处的模式.Linux(以及后来的Posix修订版)显然已经用各种标志取代了三种终端模式,这些标志的组合效果导致行为非常类似于旧的终端模式。
首先,您可能希望在尝试其他任何操作之前使用isatty(1)
(在stdout上调用isatty
)来查看您的输出是否真的是终端。
然后,您可以使用tcgetattr
将各个位的当前设置读入struct termios
。此结构包含一个名为c_oflag
的成员,用于输出模式位。在这种情况下,相关位可能是ONLCR
,也许(但我怀疑不是)OPOST
。