Код работает только с endl - очень странно

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

Я вошел в режим отладки, я следил за ходом программы, и отладчик показал мне, что в дереве есть значения. Затем я хотел отобразить только элементы первого узла, и у меня возникла та же проблема: пустая консоль.

Я спросил своего учителя, что было бы ошибкой, и он сказал мне поставить endl после cout, как это:

cout << node->keys[i] << endl;

Это сработало! Он сказал мне тогда, что, вероятно, я обратился к NULL указатель в моей программе и Eclipse ничего не говорит об этом, но ничего о том, как endl мог бы помочь.

Кто-нибудь знает, в чем может быть проблема и как это endl решает это? Я очень, очень смущен. Я не понял, как очистка буфера связана с моей функцией отображения.

5 ответов

Решение

Я немного опаздываю с ответом, и о том, как смывать, уже объясняли другие ответы, так что я хочу ответить на ваш комментарий по крайней мере об ответе Джонси.

Во-первых, причина того, что выходные данные буферизируются, заключается в том, что запись данных в некоторый выходной поток, а не в память, обычно является очень медленной операцией (это зависит от того, хотите ли вы записать файл в ssd или жесткий диск или просто на дисплей, но они все намного медленнее, чем баран).

Таким образом, C++ сначала записывает его во внутренний буфер, а на самом деле записывает на выход только когда буфер заполнен или вы очищаете поток. Это позволяет избежать медленной операции записи в большинстве выходных потоков.

Итак, теперь, почему вам нужно очистить буфер, прежде чем он отобразится... Как уже говорилось, он только фактически записывает его, чтобы вы увидели, когда буфер заполнен или он явно очищен. Теперь, когда программа завершается нормально, все потоки автоматически сбрасываются, поэтому в случае сбоя программы происходит сбой программы (сбой не приводит к сбросу буфера), поэтому ваша программа перестает отображаться.

Поскольку ваша программа отображает все правильно, когда вы добавляете endl Я думаю, вы пытаетесь вывести узел с nullptrв самом конце и сбой перед возвращением из main, Вы можете легко проверить это, добавив std::cout << "end of the program" << std::endl; как раз перед вашим returnв основном и тестирование, если оно отображается.

std::endl сбрасывает поток вывода....

cout буферизируется, выходные данные не будут отображаться немедленно, они будут буферизироваться до тех пор, пока буфер не переполнится, после чего будут отображены все буферизованные данные. Если вы хотите отобразить результат раньше, flush Это.

Вставляет символ конечной строки в выходную последовательность os и сбрасывает его, как будто вызывая os.put(os.widen('\n')), за которым следует os.flush (). [1]

Ты можешь использовать std::cout.flush(); тоже.

Как М.М. упомянул в своем ответе, как и другие выше, std::endl сбрасывает выходной поток. Это означает, что необходимо отображать или выводить результаты / вывод на стандартный источник вывода немедленно / в режиме реального времени.

С помощью '\n' вместо std::endl также приведет к аналогичному выводу, но может не отображаться сразу, если какая-то операция все еще продолжается.

Общим недостатком std::endl считается снижение производительности, хотя это может не иметь значения, если вывод передается на дисплей вместо файла - где '\n' является предпочтительным методом.

Надеюсь это поможет.

std::endl не только добавляет символ новой строки в выходной поток, но также вызывает его сброс. Я не совсем уверен, насколько большой буфер на std::cout есть, но возможно, что вы ничего не видите, потому что буфер не заполнен и, следовательно, не очищается. Вы можете попробовать позвонить cout.flush(); после добавления ваших данных (без добавления std::endl) и посмотрите, решит ли это проблему.

std::endl вставляет символ конца строки в выходную последовательность (os, в твоем случае cout) а также flush это как если бы по телефону os.put(os.widen('\n')) с последующим os.flush(),

std::cout управляет выводом в потоковый буфер определенного типа реализации (производный от std::streambuf), связанный со стандартным выходным потоком C stdout. Этот вывод буферизован (в отличие от std::cerr)

Прежде чем положить endl в ваш исходный код ваш буфер не очищался, а вывод не появлялся на вашем экране.

Другие вопросы по тегам