Как реализовать в C ++ кроссплатформенный snprintf? - PullRequest
0 голосов
/ 04 февраля 2012

Интересно, возможно ли это и как реализовать в C ++ кроссплатформенность, (C99, C ++ 0x независимый) snprintf?Есть ли такое в boost?(Интересно, что за идиома C ++ должна заменить snprintf(4)?)

Ответы [ 6 ]

6 голосов
/ 04 февраля 2012

std::ostringstream будет альтернативой использованию snprintf:

char buf[1024];
snprintf(buf, 1024, "%d%s", 4, "hello");

Эквивалент:

#include <sstream>

std::ostringstream s;
s << 4 << "hello";
// s.str().c_str(); // This returns `const char*` to constructed string.

Существует также boost :: lexical_cast :

std::string s = boost::lexical_cast<std::string>(4) +
                    boost::lexical_cast<std::string>("hello");
2 голосов
/ 04 февраля 2012

Да, есть библиотека Boost Format, которая поддерживает форматирование строк.

1 голос
/ 04 февраля 2012

Так как Boost был упомянут, есть ли что-то не так с Boost.Format?

1 голос
/ 04 февраля 2012

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

да, упоминание Qt в вопросе, помеченном как boost, может быть табу, но вопрос казался более общим, чем этот.

0 голосов
/ 21 февраля 2014

std::ostringstream или std::to_string (c ++ 11) работает как альтернатива, но если вам требуется более эффективное решение без лишних копий или у вас есть только C, а не C ++, вам может потребоваться сделать что-то еще:

MSVC не поддерживает C99 и поэтому имеет не snprintf функцию, а только самодельную: _snprintf.

Различия между MSVC _snprintf и официальным C99 (gcc, clang) snprintf:

Возвращаемое значение:

  • MSVC: вернуть -1, если размера буфера недостаточно для записи всего (не включая завершение нуля!)
  • GCC: вернуть количество символов, которое было бы записано, если бы буфер был достаточно большим

Письменные байты:

  • MSVC: писать как можно больше, не писать NULL в конце, если не осталось места
  • GCC: писать как можно больше, всегда писать завершающий NULL (исключение: buffer_size = 0)

Интересно %n Тонкость: Если вы используете %n в своем коде, MSVC оставит его унифицированным! если он прекращает синтаксический анализ, поскольку размер буфера слишком мал, GCC всегда будет записывать количество байтов, которое было бы записано, если бы буфер был достаточно большим.

Поэтому я бы предложил написать собственную функцию-оболочку mysnprintf с использованием vsnprintf / _vsnprintf, которая дает одинаковые возвращаемые значения и записывает одинаковые байты на обеих платформах (будьте осторожны: %n исправить сложнее ).

0 голосов
/ 04 февраля 2012

Когда-то мне нужно было snprintf в Windows / Linux / HP-UX. Я определил snprintf_safe, а в Linux / HP-UX я использовал snprinf, а в Windows - _snprintf. Я помню, что _snprintf имеет немного другой подход к записи '\ 0', если количество байтов, необходимое для хранения данных, превышает максимально допустимый размер. Так что надо было справиться. Во всяком случае, это был такой макрос:

#ifdef #WIN32
int snprintf_safe()
{
  // make use of _snprintf
}
#else
   #define snprintf_safe snprintf
#endif
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...