简体   繁体   English

cout c ++中的奇怪行为

[英]strange behavior in cout c++

Intro: In cout I expect any values passed by the insertion operator << to be displayed on screen. 简介:cout我希望插入运算符<<传递的任何值都将显示在屏幕上。

Normally one would think that the following code would work without fault: 通常,人们会认为以下代码可以正常运行:

int n = 0;
cout << n;

And it does, and yes, it is good practice to always use endl . 确实如此,是的,始终使用endl是一个好习惯。 But the problem I am having is very strange (to me at least). 但是我遇到的问题很奇怪(至少对我来说)。

The Problem: I have the following code: 问题:我有以下代码:

cout << " value at array point 0: "  << (list)[length -1] << endl;
cout << " Retry: " << (list)[length - 1];

list is a pointer pointing towards the 0 index memory location of an array of integers. list是一个指向整数数组的0索引存储位置的指针。 length is the array length. length是数组的长度。 You would imagine that this code would work without fault, correct? 您会想象这段代码可以正常运行,对吗? Wrong. 错误。 For some reason the second line will not display - and I hadn't the slightest clue why. 由于某种原因,第二行将不会显示-而且我丝毫不知道为什么。 Then I added endl to the end of " Retry: " out of curiosity, and it worked. 然后出于好奇,我将endl添加到" Retry: "的末尾,并且可以正常工作。 I don't know why, and it is really bothering me. 我不知道为什么,这真的困扰着我。

Thanks in advance to all help! 预先感谢所有帮助!



Basic overview of code 基本代码概述

// Prototype
void listAdd( int* list, int& length );

int main()
{
   /* this program was created for practice with dynamic memmory with arrays.
   It should be able to extend the list, destroy it, and pop from it.
   */
    int length = 0;
    int *list = NULL;

    for( int i = 0; i < 5; i ++)
    {
        listAdd( list, length );
        //listDisplay( list, length);
    }

    cout << " if this has been displayed the program ended correctly." << endl;
    return 0;
}


void listAdd(int *list, int &length) {

    int* tempList = new int[ length + 1 ];
    for( int i = 0; i < length; i ++ )
    {
        (tempList)[i] = (list)[ i ];
    }


    cout << " Enter a number: ";
    int stored = 0;
    cin >> stored;

    cout << endl;
    if ( list != NULL )
        delete[] list;

    cout << " Previous adress: " << hex << list << endl;
    list = tempList;
    cout << " New address: " << hex << list << endl << dec;

    length ++;
    cout << " Length: " << length << endl;
    (list)[length -1] = stored;
    cout << " value at array point 0: "  << (list)[length -1] << endl;
    cout << " Retry: " << (list)[length - 1];
}

You need to flush stream manually. 您需要手动刷新流。 You should use "cout.flush()" after the code you posted. 您应该在发布代码后使用“ cout.flush()”。

What "std::cout << std::endl" does is - it prints '\\n' symbol and then it flushes the stream (same as std::cout.flush() . “ std :: cout << std :: endl”的作用是-打印'\\ n'符号,然后刷新流(与std::cout.flush()相同std::cout.flush()

PS it's not correct that using "endl" is always a good practice . PS:使用“ endl”始终是一个好习惯是不正确的 You should usually use '\\n' for printing new line symbols. 通常应使用'\\ n'来打印新的线符号。 And use std::endl only in cases like these. 并仅在此类情况下使用std::endl

Streamed output is written to a buffer, and may not be written to the final destination until the stream is flushed. 流的输出将写入缓冲区,并且只有在刷新流后才能将其写入最终目的地。 std::endl will insert an end-of-line, and then flush. std::endl将插入行尾,然后刷新。 You can insert std::flush , or call the flush() member function, to flush without inserting an end-of-line, if that's what you want. 您可以插入std::flush或调用flush()成员函数进行刷新,而无需插入行尾。

it is good practice to always use "endl" 最好始终使用“ endl”

Not really. 并不是的。 Flushing too often, especially when writing to a file, can degrade performance. 经常刷新(尤其是在写入文件时)会降低性能。

endl flushes the stdout stream. endl刷新标准输出流。 Your output is probably just in the buffer waiting to be printed to the screen. 您的输出可能只是在缓冲区中,等待打印到屏幕上。 There is nothing wrong with the behavior (besides that you did expect something else). 行为没有任何问题(除了您确实有其他期望)。

Try a manual flush instead of endl. 尝试使用手动flush代替endl。 That should result in the same behavior. 那应该导致相同的行为。

Quoting cppreference : 引用cppreference

Inserts a endline character into the output sequence os and flushes it as if by calling os.put(os.widen('\\n')) followed by os.flush(). 在输出序列os中插入一个结束符,并通过调用os.put(os.widen('\\ n'))和os.flush()对其进行刷新。

So the output is just in the buffer. 因此,输出仅在缓冲区中。 Outputting more stuff - or explicitly flushing - will cause it to be displayed. 输出更多的东西-或显式冲洗-将导致显示它。

I agree with other answers stating that unnecessarily adding std::endl or more generally flushing more often than you need to is not a good practice. 我同意其他答案,认为不必要地添加std::endl或更通常比需要的刷新次数更多不是一个好习惯。

If you added an std::endl to the end of the second output and it worked, it is because endl flushes the stream buffer. 如果您在第二个输出的末尾添加了std::endl并起作用,那是因为endl刷新了流缓冲区。 Otherwise, you are waiting for the next buffer write to the screen (and if your program exits before that happens, you likely don't see it before it closes the window - it would write it out and close the program almost instantly). 否则,您将等待下一个缓冲区写入屏幕(并且如果您的程序在此之前退出,则在关闭窗口之前您可能看不到它-它会写出并几乎立即关闭程序)。

You need to flush the stream if you have not caused that to happen automatically. 如果尚未自动清除流,则需要刷新流。

Sending a newline (endl) will cause the stream to flush. 发送换行符(endl)将导致流刷新。

If you really want to flush and keep the cursor on the same line, add cout.flush() to explicitly flush the buffered stream data. 如果您确实要刷新并将光标保持在同一行,请添加cout.flush()以显式刷新缓冲的流数据。 eg: 例如:

cout << " value at array point 0: "  << (list)[length -1] << endl;
cout << " Retry: " << (list)[length - 1];
cout.flush();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM