Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C+;中对静态缓冲区执行字符串格式化+;?_C++_String_Performance_Ostringstream - Fatal编程技术网

C++ 如何在C+;中对静态缓冲区执行字符串格式化+;?

C++ 如何在C+;中对静态缓冲区执行字符串格式化+;?,c++,string,performance,ostringstream,C++,String,Performance,Ostringstream,我在一段性能要求非常高的代码中工作。我需要执行一些格式化字符串操作,但我试图避免内存分配,甚至是内部库分配 在过去,我会做类似的事情(假设C++11): < >我更愿意使用所有的C++方法,比如OSTRIGSWATH来代替旧的C函数。 我意识到我可以使用std::string::reserve和std::ostringstream提前获取空间,但这仍然会执行至少一次分配 有人有什么建议吗 提前谢谢 有人有什么建议吗 是的,使用std::ostream。我知道这是不赞成的。但我发现它对于输出到静态

我在一段性能要求非常高的代码中工作。我需要执行一些格式化字符串操作,但我试图避免内存分配,甚至是内部库分配

在过去,我会做类似的事情(假设C++11):

< >我更愿意使用所有的C++方法,比如OSTRIGSWATH来代替旧的C函数。 我意识到我可以使用std::string::reserve和std::ostringstream提前获取空间,但这仍然会执行至少一次分配

有人有什么建议吗

提前谢谢

有人有什么建议吗

是的,使用std::ostream。我知道这是不赞成的。但我发现它对于输出到静态缓冲区很有用。如果发生异常,则不存在内存泄漏的可能性。 根本没有内存分配

#include <strstream> // for std::ostrstream
#include <ostream>   // for std::ends
// :

constexpr int BUFFER_SIZE = 200;
char buffer[BUFFER_SIZE];
std::ostrstream   osout(buffer, sizeof(buffer));
osout << "Part A: " << intA << "Part B: " << intB << std::ends;
#包含//用于std::ostream
#include//for std::ends
// :
constexpr int BUFFER_SIZE=200;
字符缓冲区[缓冲区大小];
std::OSTREAM osout(缓冲区,sizeof(缓冲区));

osout我感谢所有的建议(甚至在评论中)

我很欣赏SJHowe的建议,这是问题的最简单的解决办法,但我想做的事情之一是开始为未来的C++编码,而不使用任何被蔑视的东西。 我决定采用的解决方案来自Remy Lebeau的评论:

#include <iostream>  // For std::ostream and std::streambuf
#include <cstring>   // For std::memset

template <int bufferSize>
class FixedBuffer : public std::streambuf
{
public:
   FixedBuffer()
      : std::streambuf()
   {
      std::memset(buffer, 0, sizeof(buffer));
      setp(buffer, &buffer[bufferSize-1]);         // Remember the -1 to preserve the terminator.
      setg(buffer, buffer, &buffer[bufferSize-1]); // Technically not necessary for an std::ostream.
   }

   std::string get() const
   {
      return buffer;
   }

private:
   char buffer[bufferSize];
};

//...

constexpr int BUFFER_SIZE = 200;
FixedBuffer<BUFFER_SIZE> buffer;
std::ostream ostr(&buffer);

ostr << "PartA: " << intA << std::endl << "PartB: " << intB << std::endl << std::ends;
#包括//用于std::ostream和std::streambuf
#include//For std::memset
模板
类FixedBuffer:public std::streambuf
{
公众:
FixedBuffer()
:std::streambuf()
{
std::memset(buffer,0,sizeof(buffer));
setp(buffer,&buffer[bufferSize-1]);//记住-1以保留终止符。
setg(buffer、buffer和buffer[bufferSize-1]);//从技术上讲,std::ostream不需要。
}
std::string get()常量
{
返回缓冲区;
}
私人:
字符缓冲区[bufferSize];
};
//...
constexpr int BUFFER_SIZE=200;
固定缓冲区;
std::ostream ost(&buffer);

ostr编写您自己的派生类(或找到第三方派生类),在内部使用固定缓冲区,然后您可以通过构造函数或方法将其附加到
std::ostream
(而不是
std::ostringstream
)对象。我认为“旧C函数”没有任何问题,特别是因为你需要高性能。你甚至可以尝试到一个较低的级别,使用
std::memcpy
+
std::to_chars
,速度可能会快一点。如果你是为了记录日志而这样做的,你可能只想直接使用spdlog之类的东西。你可以尝试fastformat或pantheios(两者都来自Matthew Wilson)。垫片是有前途的,但我自己从来没有坐过板凳。iostream并不是为了速度而设计的,我会选择好的旧snprintf。get方法复制整个缓冲区,这可能不是您想要的。此外,即使整个缓冲区未填充,结果字符串也具有长度
bufferSize
#include <iostream>  // For std::ostream and std::streambuf
#include <cstring>   // For std::memset

template <int bufferSize>
class FixedBuffer : public std::streambuf
{
public:
   FixedBuffer()
      : std::streambuf()
   {
      std::memset(buffer, 0, sizeof(buffer));
      setp(buffer, &buffer[bufferSize-1]);         // Remember the -1 to preserve the terminator.
      setg(buffer, buffer, &buffer[bufferSize-1]); // Technically not necessary for an std::ostream.
   }

   std::string get() const
   {
      return buffer;
   }

private:
   char buffer[bufferSize];
};

//...

constexpr int BUFFER_SIZE = 200;
FixedBuffer<BUFFER_SIZE> buffer;
std::ostream ostr(&buffer);

ostr << "PartA: " << intA << std::endl << "PartB: " << intB << std::endl << std::ends;