c++ vsnprintf处理长字符串(或奇怪字符串)时出错

c++ vsnprintf error when processing a long string(or strange)

本文关键字:字符串 出错 vsnprintf 处理 c++      更新时间:2023-10-16

这段代码的问题是什么:

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());

这里有什么问题?我该怎么解决?

非常感谢!

这里你用完了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。实际上,您可以调整输出字符串的大小并直接写入其中

您的字符串长度为512个字符,并且您在函数中分配512个字节给buffer,因此出现错误。增加缓冲区的大小。修改语句

char* buffer = new char[size];

vsnprintf()及其变体在缓冲区太小时默默地截断字符串,但它们不返回字符串的实际长度,因此您无法使用更长的缓冲区再次尝试。它们返回-1

使用_vscprintf。这将返回所需的字符数,而无需实际格式化任何内容。