处理长字符串(或奇怪的)时出现 C++ vsnprintf 错误
c++ vsnprintf error when processing a long string(or strange)
这段代码有什么问题:
std::string StringPrintf(const char* fmt, ...) {
int size = 512;
char* buffer = new char[size];
va_list vl;
va_start(vl, fmt);
int nsize = vsnprintf(buffer, size, fmt, vl);
if (size <= nsize) { //fail delete buffer and try again
delete[] buffer;
buffer = 0;
buffer = new char[nsize + 1]; //+1 for /0
nsize = vsnprintf(buffer, size, fmt, vl);
}
std::string ret(buffer);
va_end(vl);
delete[] buffer;
return ret;
}
如果我这样使用函数,它会崩溃:
string a = "x^x-SIL+zh=ang@x_x/A:x_x_x/B:x-x-x@x-x&x-x|x/C:2+x+2/D:x_x/E:x+x@x+x&x+x#x+x/F:uj_1/G:x_x/H:x=x^x=x|x/I:1=1/J:7+6-6x^x-SIL+zh=ang@x_x/A:x_x_x/B:x-x-x@x-x&x-x|x/C:2+x+2/D:x_x/E:x+x@x+x&x+x#x+x/F:uj_1/G:x_x/H:x=x^x=x|x/I:1=1/J:7+6-6 x^SIL-zh+ang=ch@2_2/A:x_0_x/B:1-x-3@1-2&1-2|x/C:2+x+2/D:x_x/E:nr+2@1+1&x+x#x+x/F:uj_1/G:x_x/H:2=1^1=6|0/I:1=1/J:7+6-6 SIL^zh-ang+ch=i@3_1/A:x_0_x/B:1-x-3@1-2&1-2|x/C:2+x+2/D:x_x/E:nr+2@1+1&x+x#x+x/F:uj_1/G:x_x/H:2=1^1=6|0/I:1=1/J:7+6-6 zh^ang-ch+i=d@1_2/A:1_0_3/B:2-x-2@2-1&2-1|i/";
string rs = StringPrintf("result=>\n%s;", a.c_str());
这里有什么问题?我该如何解决?
非常感谢!!
您的字符串长度为 512 个字符,并且您在函数中为 buffer
分配了 512 个字节,因此出现错误。增加缓冲区的大小。
更改此声明
char* buffer = new char[size];
vsnprintf()
及其变体会在缓冲区太小时静默截断字符串,但它们不会 return 字符串的实际长度,因此您无法再次尝试使用更长的字符串缓冲。他们return-1.
使用_vscprintf
。这 return 不需要实际格式化任何内容所需的字符数。
这里用完了va_list
:
int nsize = vsnprintf(buffer, size, fmt, vl);
但稍后您尝试再次使用相同的列表 vl
时它已经在末尾:
nsize = vsnprintf(buffer, size, fmt, vl)
在进行另一个 vsnprintf
调用之前,您需要开始一个新列表:
va_end(vl);
va_start(vl, fmt);
此外,为避免内存错误,请使用 vector
而不是 new char
。事实上,您可以调整输出字符串的大小并直接写入其中。
这段代码有什么问题:
std::string StringPrintf(const char* fmt, ...) {
int size = 512;
char* buffer = new char[size];
va_list vl;
va_start(vl, fmt);
int nsize = vsnprintf(buffer, size, fmt, vl);
if (size <= nsize) { //fail delete buffer and try again
delete[] buffer;
buffer = 0;
buffer = new char[nsize + 1]; //+1 for /0
nsize = vsnprintf(buffer, size, fmt, vl);
}
std::string ret(buffer);
va_end(vl);
delete[] buffer;
return ret;
}
如果我这样使用函数,它会崩溃:
string a = "x^x-SIL+zh=ang@x_x/A:x_x_x/B:x-x-x@x-x&x-x|x/C:2+x+2/D:x_x/E:x+x@x+x&x+x#x+x/F:uj_1/G:x_x/H:x=x^x=x|x/I:1=1/J:7+6-6x^x-SIL+zh=ang@x_x/A:x_x_x/B:x-x-x@x-x&x-x|x/C:2+x+2/D:x_x/E:x+x@x+x&x+x#x+x/F:uj_1/G:x_x/H:x=x^x=x|x/I:1=1/J:7+6-6 x^SIL-zh+ang=ch@2_2/A:x_0_x/B:1-x-3@1-2&1-2|x/C:2+x+2/D:x_x/E:nr+2@1+1&x+x#x+x/F:uj_1/G:x_x/H:2=1^1=6|0/I:1=1/J:7+6-6 SIL^zh-ang+ch=i@3_1/A:x_0_x/B:1-x-3@1-2&1-2|x/C:2+x+2/D:x_x/E:nr+2@1+1&x+x#x+x/F:uj_1/G:x_x/H:2=1^1=6|0/I:1=1/J:7+6-6 zh^ang-ch+i=d@1_2/A:1_0_3/B:2-x-2@2-1&2-1|i/";
string rs = StringPrintf("result=>\n%s;", a.c_str());
这里有什么问题?我该如何解决?
非常感谢!!
您的字符串长度为 512 个字符,并且您在函数中为 buffer
分配了 512 个字节,因此出现错误。增加缓冲区的大小。
更改此声明
char* buffer = new char[size];
vsnprintf()
及其变体会在缓冲区太小时静默截断字符串,但它们不会 return 字符串的实际长度,因此您无法再次尝试使用更长的字符串缓冲。他们return-1.
使用_vscprintf
。这 return 不需要实际格式化任何内容所需的字符数。
这里用完了va_list
:
int nsize = vsnprintf(buffer, size, fmt, vl);
但稍后您尝试再次使用相同的列表 vl
时它已经在末尾:
nsize = vsnprintf(buffer, size, fmt, vl)
在进行另一个 vsnprintf
调用之前,您需要开始一个新列表:
va_end(vl);
va_start(vl, fmt);
此外,为避免内存错误,请使用 vector
而不是 new char
。事实上,您可以调整输出字符串的大小并直接写入其中。