У меня есть следующий код:
std::cerr << "Hello" << std::endl;
std::cerr << "World" << std::endl;
…что обычно было бы здорово.
Но: Я запускаю его в программе порта Erlang, и Erlang сделал … что-то для терминала, означающее, что \ n больше не преобразуется в CRLF, что означает, что мой вывод выглядит как …
Hello
World
Что Эрланг сделал с моим терминалом? Как мне это обнаружить? Как я могу получить std::endl
выводить \r\n
в этом случае?
Примечание: это (вероятно) не только потому, что Эрланг проглатывает stderr из моей программы и запутывает перевод строки. Если я использую обычный printf("Hello\n")
в NIF я вижу ту же проблему.
Не использовать ::std::endl
на первом месте. Это на самом деле не делает то, что вы хотите. Это всегда выводит '\n'
и промывает поток. Очистка потока — это огромное и ненужное снижение производительности в большинстве случаев.
И по '\n'
Я имею в виду именно это. Фактический, буквальный,'\n'
, Это не делает какой-либо перевод или что-то, что люди думают, что это делает. Просто квартира '\n'
и флеш, даже на винде. Перевод новой строки, который вы получаете под окнами, обрабатывается нижним уровнем iostream
объектов и контролируется тем, находится ли поток в binary
Режим.
То, что Эрланг сделал с вашим терминалом, вероятно, переведено в режим CBREAK. Здесь есть один или два хороших вопроса, на которых есть ответы, которые описывают различия между режимами необработанного, готового и cbreak-драйвера терминала в Unix.
Возможно, вы сможете вручную вернуть терминал в режим приготовления. Единственная причина, по которой Эрланг сделал это, заключается в том, что обычно вы получаете только то, что набирают люди, когда нажимают ввод. CBREAK позволяет получать каждый символ по мере его ввода.
Вы также можете проверить, в каком режиме находится терминал. Linux (и более поздние версии Posix), по-видимому, заменили три режима терминала различными флагами, в результате чего комбинированный эффект приводит к поведению, которое очень похоже на старые режимы терминала.
Во-первых, вы, вероятно, хотите использовать isatty(1)
(вызов isatty
на стандартный вывод), чтобы увидеть, действительно ли ваш вывод является терминалом, прежде чем пытаться что-либо еще.
Затем вы можете использовать tcgetattr
чтобы прочитать текущие настройки для различных битов в struct termios
, Эта структура содержит член с именем c_oflag
для битов выходного режима. Соответствующие биты в этом случае, вероятно, ONLCR
и возможно (но я подозреваю, что нет) OPOST
,
Других решений пока нет …