C ++: почему этот код работает только при использовании \ n? - PullRequest
4 голосов
/ 04 февраля 2020

Следующий код C ++ отлично работает при компиляции с g ++ в Ubuntu 18.04:

#include <iostream>

using namespace std;

void wait(){
  int t0 = time(0);
  while(true){
    if(time(0) >= t0 + 1){
      return;
    }
  }
}
int main(){
  while(true){
    cout << "tick\n";  //Line 15
    wait();
  }
}

Это вывод, где каждую секунду появляется tick:

tick
tick
tick
tick
tick

Однако когда удаление \n в строке 15, кажется, просто застряло где-то, и ничего не происходит. Что именно \n делает с кодом? Что мне делать, если я не хочу печатать новую строку после каждого цикла? (я предполагаю, что называть это ошибкой в ​​C ++ было бы немного высокомерно и неправильно)

Кроме того, я знаю, что это, вероятно, очень плохой способ построения функции задержки, я ' Я просто бездельничаю.

1 Ответ

10 голосов
/ 04 февраля 2020

Кажется, что ваша реализация std::cout записывает в C поток вывода stdout. И stdout по умолчанию (при подключении к терминалу) с буферизацией строки .

Буферизация строки означает, что выход буферизуется внутри, пока не будет добавлена ​​новая строка ('\n') в буфер. Затем буфер очищается и фактически записывается в терминал.


Вы можете явно буферизовать буфер sh, используя манипулятор ввода-вывода C ++ std::flush, как в

cout << "tick" << std::flush;

Это немедленно вызовет буфер sh и запишет его в терминал. Но без новой строки. Чтобы добавить новую строку, вы можете использовать std::endl:

cout << "tick" << std::endl;  // Add newline and flush

Но обратите внимание, что явный дополнительный грипп sh здесь не нужен, так как новая строка сама очищает буфер. Поэтому использование std::endl будет сначала вызывать flu sh буфер один раз из-за новой строки, а затем flu sh пустой буфер из-за явной семантики очистки.

Рекомендуется не использовать std::flush (или std::endl), если вам не нужно. В большинстве случаев это действительно не нужно.

...