使编译器不会自动刷新缓冲区(make the compiler not to automatical

2019-10-18 10:52发布

为什么下面的代码自动刷新缓冲区停止编译器?

cout.sync_with_stdio(false);
cin.tie(nullptr);
cout << "hello";
cout << "world";
int a;
cin >> a;

输出:

helloworld

我使用的Visual Studio 2012旗舰版

Answer 1:

据我所知,流可以刷新每当执行喜欢这样做,也就是说,不能保证该流将插入操作之后被刷新。 但是,您可以使用这些操纵器之一,以确保您的流被刷新(这是唯一我知道的,所以如果有人知道别人的,请评论):

  • std::endl -插入新行到流并刷新它,
  • std::flush -冲洗只是流,
  • std::(no)unitbuf -启用/禁用冲洗每个插入操作后的流。


Answer 2:

该标准允许实现冲洗感觉它的任何时间,但从实施点的质量,人真的不期望在这里冲洗。 您可以尝试添加setbuf ,告诉std::cin使用指定的缓冲区:

std::cout.rdbuf()->setbuf( buffer, sizeof(buffer) );

此外,该标准并不能保证什么,但如果这是不尊重,我会考虑质量坏到足以保证一个bug报告。

最后,如果损坏程度严重,你总是可以插入一个过滤流缓冲这是你想要的缓冲。 你不应该有,但它不会是第一次,我们已经不得不编写额外的代码来解决缺乏的编译器和库的质量。 如果你正在做的是简单的输出(不寻求或任何东西,类似下面应该做的伎俩:

class BufferingOutStreambuf : public std::streambuf
{
    std::streambuf* myDest;
    std::ostream* myOwner;
    std::vector<char> myBuffer;

    static size_t const bufferSize = 1000;
protected:
    virtual int underflow( int ch )
    {
        return sync() == -1 
            ? EOF
            : sputc( ch );
    }
    virtual int sync()
    {
        int results = 0;
        if ( pptr() != pbase() ) {
            if ( myDest->sputn( pbase(), pptr() - pbase() )
                    != pptr() - pbase() ) {
                results = -1;
            }
        }
        setp( &myBuffer[0], &myBuffer[0] + myBuffer.size() );
        return results;
    }
public:
    BufferingOutStreambuf( std::streambuf* dest )
        : myDest( dest )
        , myOwner( NULL )
        , myBuffer( bufferSize )
    {
        setp( &myBuffer[0], &myBuffer[0] + myBuffer.size() );
    }

    BufferingOutStreambuf( std::ostream& dest )
        : myDest( dest.rdbuf() )
        , myOwner( &dest )
        , myBuffer( bufferSize )
    {
        setp( &myBuffer[0], &myBuffer[0] + myBuffer.size() );
        myOwner->rdbuf( this );
    }

    ~BufferingOutStreambuf()
    {
        if ( myOwner != NULL ) {
            myOwner->rdbuf( myDest );
        }
    }
};

然后,只需做:

BufferingOutStreambuf buffer( std::cout );

如第一行main 。 (有人可能会说的iostream应该被设计成这样从一开始工作,以过滤流缓冲缓冲代码转换,但它不是,这不应该是必要的一个体面的实现。)



文章来源: make the compiler not to automatically flush the buffer