Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Различия между '\n' и std::endl

#cpp


Есть такой код:

int main() 
{ 
    cout << "Hello, world!" << endl;
}


Второй код:

int main() 
{ 
    cout << "Hello, world!\n";
}


Я знаю, что endl делает перенос и очищает буфер (flush). Но почему-то не вижу разницы,
что с endl, что с \n, результат один - отображается Hello, world!

Как переписать код так, чтобы увидеть разницу с endl и \n?
    


Ответы

Ответ 1



Думаю, что проблема в буферизации вывода. В C++ потоки ввода и вывода могут быть в одном из трёх состояний: небуферизирован (любой вывод сразу попадает в целевой файл/пайп/на консоль), буферизирован построчно (символы попадают в вывод после окончания каждой строки, исчерпания внутреннего буфера или закрытия потока), и полностью буферизован (символы попадают в вывод лишь после исчерпания внутреннего буфера или закрытия потока). Майкрософтовская реализация стандартной библиотеки никогда не делает построчную буферизацию (почитайте ответ от Stephan T. Lavavej), имплементации на линуксе обычно делают. В этом ответе содержится цитата из стандарта (C11 7.21.3 §7): the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device (это относится к чистому C). У C++ та же политика, согласно этому ответу: C++11 27.4.2 [narrow.stream.objects]/3 : The object cout controls output to a stream buffer associated with the object stdout. Это означает, что если вывод производится на консоль, а не в файл, то вы увидите всегда полную строчку после \n. А вот если вывод перенаправлен, то произойдёт буферизация. Вот пример. Рассмотрим код: #include "stdafx.h" #include #include #include int main() { std::cout.sync_with_stdio(false); std::cout << "this is " << "\n"; std::this_thread::sleep_for(std::chrono::seconds(10)); std::cout << "SPARTAAAA!!!111" << std::endl; return 0; } в MSVC 2015. Если запустить программу обыкновенным образом, мы увидим сначала this is, и лишь через 10 секунд SPARTA. А если запустить программу так: a.exe >x.txt, и заглянуть через пару секунд после запуска в файл x.txt, то вы не увидите там ничего до окончания работы программы. Если заменить "\n" на std::endl, вывод в файл работает так же, как и на консоль. Обновление: в MSVC 2015 установить буферизацию std::cout можно вручную (идея с благодарностью украдена подсмотрена в этом ответе): std::cout.sync_with_stdio(false); char mybuf[1024]; std::cout.rdbuf()->pubsetbuf(mybuf, 1024); std::cout << "this is " << "\n"; std::this_thread::sleep_for(std::chrono::seconds(10)); std::cout << "SPARTAAAA!!!111" << std::endl; return 0; Этот код выводит текст только после std::endl.

Ответ 2



Выведи еще что-то, чтобы увидеть разницу int main() { cout << "Hello, world1!" << endl; cout << "Hello, world2!" << endl; } Выведет: Hello, world1! Hello, world2! Но int main() { cout << "Hello, world1!"; cout << "Hello, world2!"; } Выведет: Hello, world1!Hello, world2! endl всегда flushит поток, сбрасывая буфера. \n же просто пихает в поток символ начала новой строки. Разница еще в том, что \n быстрее

Комментариев нет:

Отправить комментарий