C++ sprintf结果长度的估计
我需要估计在C++ sprintf结果长度的估计,c++,C++,我需要估计在sprintf操作中获得的字符串的长度。我怎样才能做到这一点。换句话说,我如何避免在下面的代码片段中对值50进行编码 double sum; char* resultString; .. resultString = new char[50]; //how can I avoid hardcoding 50 here? sprintf(resultString,"[%e]",sum); 使用snprintf(字符*缓冲区,整数大小,常量字符*格式,…)sprintf不安全 但是我
sprintf
操作中获得的字符串的长度。我怎样才能做到这一点。换句话说,我如何避免在下面的代码片段中对值50
进行编码
double sum;
char* resultString;
..
resultString = new char[50]; //how can I avoid hardcoding 50 here?
sprintf(resultString,"[%e]",sum);
使用snprintf(字符*缓冲区,整数大小,常量字符*格式,…)代码><代码>sprintf
不安全
<>但是我读到你使用C++,所以我会使用一个这样的连串流:
#include <iostream>
#include <sstream>
double sum;
std::stringstream buf(std::stringstream::in | std::stringstream::out);
std::string resultString;
..
buf << "[" << std::scientific << sum << "]";
resultString = buf.str();
#包括
#包括
双和;
std::stringstream buf(std::stringstream::in | std::stringstream::out);
std::字符串结果字符串;
..
buf正确的方法是不使用sprintf。在C++中有许多可扩展的、安全的方式来格式化输出(包括但不限于标准的IoSooFunts)。如果您使用C编写代码,请使用snprintf。避免这一切的最佳方法是使用std::stringstream
:
std::stringstream buffer;
buffer << std::scientific << sum;
std::string resultString = buffer.str();
std::stringstream缓冲区;
buffersnprintf
返回如果缓冲区足够大,将写入的字符数。您可以调用它两次,一次是获取长度,另一次是实际格式化字符串。一个很好的快速方法是使用固定大小的缓冲区和snprintf
,它返回如果缓冲区足够大,它将打印的字符数。如果该返回值指示缓冲区不够大,则使用malloc()
或具有已知大小的new。一个较慢但更简单的替代方法是查找总是从堆中分配的asprintf()
。您可以在几行中实现您自己的asprintf()
snprintf()
。使用类似printf的函数时,您可以选择为每个数字提供长度
printf(“%.2s”,“12345”)
本例仅打印前两个字符。通过这种方式,您可以估计/限制所需的最大尺寸
除此之外,还有许多其他人建议的好答案通常,使用std::stringstream是正确的答案。
然而,有时,在连接C代码时,使用printf(fmt,…)是必要的,所以std::stringstream是不可能的。
在这些情况下,仍可以按如下方式格式化可变长度字符串:
static void append_format(std::string& s, const char* format, va_list vl)
{
auto cur_length = s.length();
auto sz = vsnprintf(NULL, 0, format, vl);
s.resize(cur_length + sz);
auto sz2 = vsnprintf(&s[cur_length], sz + 1, format, vl);
assert(sz2 == sz);
}
static void example_usage()
{
std::string s;
append_format(s, "%s %dD world", "hello", 3); // s == "hello 3D world"
append_format(s, ", PI= ~%f", 3.14); // s == "hello 3D world, PI= ~3.14"
std::cout << s;
}
static void append_格式(std::string&s,const char*格式,va_list vl)
{
自动电流长度=s.长度();
自动sz=vsnprintf(NULL,0,格式,vl);
s、 调整大小(cur_长度+sz);
自动sz2=vsnprintf(&s[cur_length],sz+1,格式,vl);
断言(sz2==sz);
}
静态void示例_用法()
{
std::字符串s;
附加_格式,“%s%dD world”,“hello”,3);//s==“hello 3D world”
附加_格式(s,,,PI=~%f,,,3.14);//s==“你好,3D世界,PI=~3.14”
STD::为什么你使用C字符串而不是C++ <代码>字符串 [某些初始化变量]中发送变量
。我收到一个错误错误:嵌套名称说明符中使用了不完整的类型“std::stringstream”
我正在执行以下操作,但为cresult获取了一个空值。sprintf版本正在工作。stringstream buf(stringstream::in);string resultString;buf已修复。显然,您需要std::stringstream::out
用于::str();
。您不需要in | out
。它们是默认值。我更喜欢stringstream随时打印f,但有时在与旧代码交互时无法避免。有关该场景,请参阅下面的答案。