Я уже использовал boost :: format во многих случаях, но я нашел тот, для которого реализация Windows не реагирует так, как я ожидал, потому что она выдает исключение
boost::bad_format_string: format-string is ill-formed
Я использую макрос для определения формата вывода шестнадцатеричного числа для другой платформы:
#if (defined(WIN32) || defined(WIN64))
#define FORMATUI64X_09 "%09I64X"#define FORMATUI64X_016 "%016I64X"#else
#if defined __x86_64__
#define FORMATUI64X_09 "%09lX"#define FORMATUI64X_016 "%016lX"#else
#define FORMATUI64X_09 "%09llX"#define FORMATUI64X_016 "%016llX"#endif
#endif
и формат вызова, как показано ниже:
string msg = (boost::format("0x"FORMATUI64X_016"(hex) \t %i \t %d \t %s \t %i\t ") % an uint64_t % an int % an uint % a char* % an uint).str();
Заметьте, что я использую синтаксис, отлично работающий с ‘fprintf’.
Я полагаю, что он взят из формата ‘uint64_t’ в виде гекса, но знаете ли вы, чтобы написать ту же строку, чтобы она работала на всех платформах?
I64X
не является допустимой спецификацией формата для boost::format
(это специфично для Microsoft). Типы спецификации формата не зависят от платформы. Boost не использует [sf]printf
подпрограммы, предоставляемые средой выполнения вашей реализации, поэтому тот факт, что она работает с Visual Studio fprintf
на самом деле не влияет на то, что boost::format
поддерживает. Вы должны использовать либо %lX
или же %llX
, как это делает ваше предложение, отличное от Windows.
Я бы, наверное, просто использовал %llX
везде и привести выходные переменные к long long
Например:
static_assert(sizeof(unsigned long long) >= sizeof(uint64_t), "long long must be >= 64 bits");
auto s = (boost::format("0x%016llx") % static_cast<unsigned long long>(u64)).str();
Это должно работать везде, где unsigned long long
достаточно, чтобы представлять uint64_t
и вы можете добавить статическое утверждение (как показано), чтобы убедиться в этом.
Других решений пока нет …