Как мне выполнить форматирование строки в статический буфер в C ++? - PullRequest
0 голосов
/ 03 июля 2018

Я работаю в разделе кода с очень высокими требованиями к производительности. Мне нужно выполнить некоторые операции с отформатированными строками, но я стараюсь избегать выделения памяти, даже внутренней библиотеки.

В прошлом я бы делал что-то похожее на следующее (предполагая C ++ 11):

constexpr int BUFFER_SIZE = 200;
char buffer[BUFFER_SIZE];
int index = 0;
index += snprintf(&buffer[index], BUFFER_SIZE-index, "Part A: %d\n", intA);
index += snprintf(&buffer[index], BUFFER_SIZE-index, "Part B: %d\n", intB);
// etc.

Я бы предпочел использовать все методы C ++, такие как ostringstream, чтобы сделать это вместо старых функций C.

Я понимаю, что мог бы использовать std :: string :: reserve и std :: ostringstream для заблаговременного получения пространства, но при этом все равно будет выполнено хотя бы одно выделение.

У кого-нибудь есть предложения?

Спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 09 июля 2018

Спасибо всем, кто разместил предложения (даже в комментариях).

Я ценю предложение SJHowe, которое является кратчайшим решением проблемы, но одна из вещей, которые я собираюсь сделать с этой попыткой, - это начать писать код для C ++ будущего, а не использовать что-либо устаревшее.

Решение, которое я решил использовать, основано на комментарии Реми Лебо:

#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;
0 голосов
/ 04 июля 2018

У кого-нибудь есть предложения?

Да, используйте std :: ostrstream. Я знаю, что это устарело. Но я считаю это полезным для вывода в статические буферы. Нет возможности утечки памяти, если происходит исключение. Нет выделения памяти вообще.

#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;
...