如何让std :: endl输出" \ r \ n"如果有必要吗?

时间:2017-10-12 14:58:40

标签: c++ erlang

我已获得以下代码:

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"),我看到同样的问题。

1 个答案:

答案 0 :(得分:2)

首先不要使用::std::endl。它并没有真正做你想要的。它始终输出'\n'并刷新流。在大多数情况下,刷新流是一个巨大且不必要的性能。

'\n'我的意思就是这样。实际的文字'\n'。它不做任何类型的翻译或人们认为它做的任何事情。即使在Windows上,也只是一个平坦的'\n'和同花。您在Windows下获得的换行符由较低级iostream工具处理,并受流是否处于binary模式控制。

Erlang对您的终端做了什么可能是将其置于CBREAK模式。这里有一个很好的问题,有一些答案描述了Unix中raw,cooked和cbreak终端驱动程序模式之间的差异。

您可以手动将终端设置回熟化模式。 Erlang这样做的唯一原因是,通常你只能得到人们输入时键入的内容。 CBREAK可让您输入所有字符。

你也可以测试自己终端所处的模式.Linux(以及后来的Pos​​ix修订版)显然已经用各种标志取代了三种终端模式,这些标志的组合效果导致行为非常类似于旧的终端模式。

首先,您可能希望在尝试其他任何操作之前使用isatty(1)(在stdout上调用isatty)来查看您的输出是否真的是终端。

然后,您可以使用tcgetattr将各个位的当前设置读入struct termios。此结构包含一个名为c_oflag的成员,用于输出模式位。在这种情况下,相关位可能是ONLCR,也许(但我怀疑不是)OPOST