C ++ iostream使用stringstream的损坏 [英] C++ iostream Corruption using stringstream

查看:121
本文介绍了C ++ iostream使用stringstream的损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个非常简单的线程安全记录器。理想情况下,我希望它像 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)



(根据 http://www.cplusplus.com/reference/iostream/stringstream/stringstream/ ) 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 with std::stringstream("Another ", stringstream::in | stringstream::out | std::stringstream::ate)

(as per http://www.cplusplus.com/reference/iostream/stringstream/stringstream/ )

这篇关于C ++ iostream使用stringstream的损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆