问题描述
我想写一个非常简单的线程安全记录器。理想情况下,我希望它像 std :: cout
工作,其中你可以重载<<
操作员,并有一切神奇地显示在日志中。我在Windows机器上,所以这里是我尝试的方法:
// Threadsafe logger
class Logger
{
public:
Logger()
{
InitializeCriticalSection(& s);
}
〜Logger()
{
DeleteCriticalSection(& s);
}
void Log(std :: ostream const& os)
{
EnterCriticalSection(& s);
// std :: cout<< static_cast< std :: stringstream const&>(os).str();
std :: cout<< os.rdbuf();
LeaveCriticalSection(& s);
}
private:
CRITICAL_SECTION s;
};注意,我已经尝试了两种方法到 Log() code>函数。我接受 ostream
的原因是因为这是 stringstream
似乎在< ;
运算符被调用。 Log()
函数的两个变体在运行此代码时都会以同样的方式失败: #include< iostream>
#include< sstream>
#include< Windows.h>
int main(int argc,char * argv [])
{
Logger logger;
//logger.Log(std::stringstream(\"Test));
logger.Log(std :: stringstream(Another)<<test);
std :: cin.get();
}
输出第一行(Test Log函数的变体。第二行显示错误的输出:
testher
这显然 test
写在另一个
。我缺少这些流的工作方式是什么?我尝试了一个 flush
调用希望能修复的东西,但它什么也没有。
如何获得尝试在线程安全的日志记录器正确地工作与流?
解决方案问题不是与记录器,你使用stringstream。
当std :: stringstream初始化时,流的位置指示符位于流的开头。
现在当你开始使用'
要解决这个问题,你可以使用
来初始化stringstream std :: stringstream(Another,stringstream :: in | stringstream :: out | std :: stringstream :: ate)
(根据) p>
I'm trying to write a really simple thread-safe logger. Ideally, I wanted it to work just like std::cout
, wherein you could just overload the <<
operator and have everything magically show up in the log. I'm on a Windows machine, so here's the approach I tried:
// Threadsafe logger
class Logger
{
public:
Logger()
{
InitializeCriticalSection(&s);
}
~Logger()
{
DeleteCriticalSection(&s);
}
void Log(std::ostream const& os)
{
EnterCriticalSection(&s);
//std::cout << static_cast<std::stringstream const&>(os).str();
std::cout << os.rdbuf();
LeaveCriticalSection(&s);
}
private:
CRITICAL_SECTION s;
};
Notice that I've tried two approaches to the Log()
function. The reason I accept an ostream
is because that's what a stringstream
seems to produce after the <<
operator is called. Both variants of the Log()
function fail in the same way when I run this code:
#include <iostream>
#include <sstream>
#include <Windows.h>
int main(int argc, char* argv[])
{
Logger logger;
//logger.Log(std::stringstream("Test"));
logger.Log(std::stringstream("Another ") << "test");
std::cin.get();
}
Outputting the first line ("Test") works correctly and displays properly using both variants of the Log function. The second line outputs a mangled output:
testher
which is obviously test
written over Another
. What am I missing about the way these streams work? I tried making a flush
call hoping that would fix things, but it did nothing.
How can I get this attempt at a thread-safe logger working correctly with the streams?
解决方案 The problem isn't with the logger, rather it's with your use of stringstream.When std::stringstream is initialized, the stream's position indicator is positioned at the beginning of the stream.
Now when you start writing to the string using '<<', you start writing at the position indicator, replacing whatever was there before.
To work around this, you can initialize the stringstream withstd::stringstream("Another ", stringstream::in | stringstream::out | std::stringstream::ate)
(as per http://www.cplusplus.com/reference/iostream/stringstream/stringstream/ )
这篇关于C ++ iostream使用stringstream的损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!