我相信其他人会告诉你使用 BOOST。因此,为了提供不依赖于 BOOST 的解决方案:
我经常遇到同样的问题,以至于我放弃并编写了自己的辅助宏来输入 %s 而不是任何品牌的%llu
或%lu
或其他什么。我还发现它有助于保持健全的格式字符串设计,并提供更好(和更一致)的十六进制和指针打印输出。有两个警告:
你不能轻易地组合额外的格式参数(左/右对齐、填充等)——但是你也不能用LU
宏真正做到这一点。
这种方法确实为格式化和打印字符串的任务增加了额外的开销。但是,我编写了性能关键型应用程序,除了 Microsoft 的 Visual C++ 调试版本(由于所有内部验证和损坏检查,分配和释放堆内存的时间比正常情况要长约 200 倍)之外,我没有注意到这是一个问题。
这是一个比较:
printf( "Value1: " LU ", Value2: " LU, somevar1, somevar2 );
对比
printf( "Value1: %s, Value2: %s", cStrDec(somevar1), cStrDec(somevar2) );
为了使它工作,我使用了一组宏和模板,如下所示:
#define cStrHex( value ) StrHex ( value ).c_str()
#define cStrDec( value ) StrDecimal( value ).c_str()
std::string StrDecimal( const uint64_t& src )
{
return StrFormat( "%u%u", uint32_t(src>>32), uint32_t(src) );
}
std::string StrDecimal( const int64_t& src )
{
return StrFormat( "%d%u", uint32_t(src>>32), uint32_t(src) );
}
std::string StrDecimal( const uint32_t& src )
{
return StrFormat( "%u", src );
}
std::string StrDecimal( const int32_t& src )
{
return StrFormat( "%d", src );
}
std::string StrHex( const uint64_t& src, const char* sep="_" )
{
return StrFormat( "0x%08x%s%08x", uint32_t(src>>32), sep, uint32_t(src) );
}
std::string StrHex( const int64_t& src, const char* sep="_" )
{
return StrFormat( "0x%08x%s%08x", uint32_t(src>>32), sep, uint32_t(src) );
}
// Repeat implementations for int32_t, int16_t, int8_t, etc.
// I also did versions for 128-bit and 256-bit SIMD types, since I use those.
// [...]
我的字符串格式化函数基于现在首选的直接格式化为 std::string 的方法,它看起来像这样:
std::string StrFormatV( const char* fmt, va_list list )
{
#ifdef _MSC_VER
int destSize = _vscprintf( fmt, list );
#else
va_list l2;
va_copy(l2, list);
int destSize = vsnprintf( nullptr, 0, fmt, l2 );
va_end(l2);
#endif
std::string result;
result.resize( destSize );
if (destSize!=0)
vsnprintf( &result[0], destSize+1, fmt, list );
return result;
}
std::string StrFormat( const char* fmt, ... )
{
va_list list;
va_start( list, fmt );
std::string result = StrFormatV( fmt, list );
va_end( list );
return *this;
}