希望ostringstream修改传递的字符串

时间:2015-03-12 18:04:27

标签: c++ string visual-studio-2010 c++03 ostringstream

我希望std::ostringstream修改我传递的字符串:

#include <string>
#include <iostream>
#include <sstream>

void My_Function(std::string& error_message)
{
  std::ostringstream error_stream(error_message);
  // For Nipun Talukdar:
  /* Perform some operations */
  if (/* operation failed */)
  {
      error_stream << "Failure at line: "
                   << __LINE__
                   << ", in source file: "
                   << __FILE__
                   << "\n";
  }
  return;
}

int main(void)
{
  std::string error_message;
  My_Function(error_message);
  std::cout << "Error is: \""
            << error_message
            << "\"\n";
  return 0;
}

使用上面的代码,error_message的输出为空。

这是因为,according to cppreference.comstd::basic_ostream的构造函数采用std::streamconst std::string 引用}。这意味着std::basic_ostringstream不会修改传递给它的字符串。引用的参考文献甚至说std::ostringstream 将传递给它的字符串的副本

为了解决这个问题,我改变了我的功能:

void My_Second_Function(std::string& error_message)
{
  std::ostringstream error_stream;
  error_stream << "Failure at line: "
               << __LINE__
               << "\n";
  error_message = error_stream.str();  // This is not efficient, making a copy!
  return;
}

是否有更有效的方法对字符串执行格式化输出,例如直接写入(即无需从流中复制)?

我使用的是Visual Studio 2010,,它不支持C ++ 11 。由于商店的考虑,升级到2013年的理由没有通过。所以我不能使用C ++ 11或C ++ 14的功能。

1 个答案:

答案 0 :(得分:1)

使用流缓冲区并将put指针设置为字符串的内部数据:

struct nocopy : std::streambuf
{
    nocopy(std::string& str)
    { this->setp(&str[0], &str[0] + str.size()); }
};

struct nocopy_stream : virtual private nocopy, std::ostream
{
    nocopy_stream(std::string& str)
        : nocopy(str)
        , std::ostream(this)
    { }
};

void My_Function(std::string& error_message)
{
  nocopy_stream error_stream(error_message);
  error_stream << "Failure at line: "
               << __LINE__
               << "\n";
}

int main(void)
{
  std::string error_message;
  error_message.resize(1000);

  My_Function(error_message);
  std::cout << "Error is: \""
            << error_message
            << "\"\n";
}

对于此示例,error_message必须设置为足够大的大小,因为我们不会覆盖overflow()并且基类版本不执行任何操作。您可以覆盖它以执行正确的调整大小。