为什么下面的代码不会阻止编译器自动刷新缓冲区?
cout.sync_with_stdio(false);
cin.tie(nullptr);
cout << "hello";
cout << "world";
int a;
cin >> a;
输出:
helloworld
我正在使用 Visual Studio 2012 Ultimate
为什么下面的代码不会阻止编译器自动刷新缓冲区?
cout.sync_with_stdio(false);
cin.tie(nullptr);
cout << "hello";
cout << "world";
int a;
cin >> a;
输出:
helloworld
我正在使用 Visual Studio 2012 Ultimate
AFAIK,只要实现喜欢这样做,就可以刷新流,即不能保证在插入操作后会刷新流。但是,您可以使用这些操纵器之一来确保您的流被刷新(这些是我所知道的唯一一个,所以如果有人知道其他人,请发表评论):
std::endl
- 在流中插入换行符并刷新它,std::flush
- 只是刷新流,std::(no)unitbuf
- 在每次插入操作后启用/禁用刷新流。该标准允许实现在任何时候刷新,但从实现质量的角度来看,人们真的不希望在这里刷新。您可以尝试添加一个setbuf
,告诉std::cin
使用您指定的缓冲区:
std::cout.rdbuf()->setbuf( buffer, sizeof(buffer) );
同样,该标准并不能保证任何事情,但如果不尊重这一点,我会认为质量差到足以保证报告错误。
最后,如果情况变得更糟,您总是可以插入一个过滤流缓冲区来执行您想要的缓冲。您不应该这样做,但这不是我们第一次不得不编写额外的代码来解决编译器或库中缺乏质量的问题。如果您所做的只是简单的输出(没有搜索或其他任何操作,则类似以下内容应该可以解决问题:
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 应该从一开始就被设计成这样工作,过滤 streambuf 以进行缓冲和代码转换。但事实并非如此,而且对于一个体面的实现来说,这不应该是必需的。)