我sprintf
在C++ 11中使用函数,方法如下:
std::string toString()
{
std::string output;
uint32_t strSize=512;
do
{
output.reserve(strSize);
int ret = sprintf(output.c_str(), "Type=%u Version=%u ContentType=%u contentFormatVersion=%u magic=%04x Seg=%u",
INDEX_RECORD_TYPE_SERIALIZATION_HEADER,
FORAMT_VERSION,
contentType,
contentFormatVersion,
magic,
segmentId);
strSize *= 2;
} while (ret < 0);
return output;
}
Run Code Online (Sandbox Code Playgroud)
有没有比这更好的方法来检查每次保留的空间是否足够?为了将来添加更多东西的可能性.
Dev*_*lar 15
您的构造 - 写入从缓冲区接收的缓冲区c_str()
是未定义的行为,即使您事先检查了字符串的容量.(返回值是指向const char 的指针,并且函数本身标记为const,原因.)
不要混用C和C++,特别是不要写入内部对象表示.(这打破了非常基本的OOP.)使用C++,对于类型安全而不会遇到转换说明符/参数不匹配,如果没有别的.
std::ostringstream s;
s << "Type=" << INDEX_RECORD_TYPE_SERIALIZATION_HEADER
<< " Version=" << FORMAT_VERSION
// ...and so on...
;
std::string output = s.str();
Run Code Online (Sandbox Code Playgroud)
替代方案:
std::string output = "Type=" + std::to_string( INDEX_RECORD_TYPE_SERIALIZATION_HEADER )
+ " Version=" + std::to_string( FORMAT_VERSION )
// ...and so on...
;
Run Code Online (Sandbox Code Playgroud)
其他答案中显示的C++模式更好,但为了完整性,这里有一个正确的方法sprintf
:
auto format = "your %x format %d string %s";
auto size = std::snprintf(nullptr, 0, format /* Arguments go here*/);
std::string output(size + 1, '\0');
std::sprintf(&output[0], format, /* Arguments go here*/);
Run Code Online (Sandbox Code Playgroud)
注意
resize
你的字符串.reserve
不会改变缓冲区的大小.在我的例子中,我直接构造正确大小的字符串.c_str()
返回一个const char*
.你可能不会把它传递给sprintf
.std::string
在C++ 11之前,缓冲区不保证是连续的,这依赖于该保证.如果您需要支持异国预C++ 11个符合使用绳索实施平台std::string
,那么你可能会更好过冲刺到std::vector<char>
第一,然后复制向量的字符串.小智 6
我们可以混合这里的代码/sf/answers/2583678961/和这里的/sf/answers/508011521/,结果将是这样的:
template <typename ...Args>
std::string stringWithFormat(const std::string& format, Args && ...args)
{
auto size = std::snprintf(nullptr, 0, format.c_str(), std::forward<Args>(args)...);
std::string output(size + 1, '\0');
std::sprintf(&output[0], format.c_str(), std::forward<Args>(args)...);
return output;
}
Run Code Online (Sandbox Code Playgroud)