当前位置: 首页 > 知识库问答 >
问题:

c++ - 为什么输出的 vsnprintf 的返回值随着执行次数不同而变化呢?

洪飞扬
2023-11-23

为什么输出的 vsnprintf 的返回值随着执行次数不同而变化呢?

man vsnrpintf 手册上说的返回值是写入最终的字符串长度(如下截图中:the final string),但是实际测试并不是?
按文档说法:返回值应该为3;
实际测试结果:不为3,也不为10,而是14、15、16这样变化的数。
image.png

void foo(const char* format, ...){    va_list ap;    va_start(ap, format);    int res1 = vsnprintf(NULL, 0, format, ap);    printf("====res1=%d\n", res1);    char buf[200] = {'\0'};    memset(buf, 0, 200);    int res2 = vsnprintf(buf, 3, format, ap);    printf("====res2=%d, buf=%s\n", res2, buf);  //多次直行a.out,值为什么不同呢?    va_end(ap);}int main()  {    foo("say=%d\n", 10000);    return 0;}

输出:
./a.out
====res1=10
====res2=16, buf=sa

./a.out
====res1=10
====res2=14, buf=sa

./a.out
====res1=10
====res2=15, buf=sa

共有2个答案

花飞尘
2023-11-23

va_list 在第一次调用的时候被消耗完了。
第二次调用的时候里面已经不是有意义的内容了。
如果要重新读的话,需要用 va_start 生成一个新的 va_list 。

盖嘉庆
2023-11-23

这个问题涉及到 vsnprintf 函数的返回值和行为。vsnprintf 函数是 C 语言中的一个函数,用于格式化字符串。它接收一个格式化字符串和一系列参数,然后将格式化的字符串写入到一个缓冲区中。

vsnprintf 的返回值通常表示写入到缓冲区中的字符数,不包括终止的空字符。在你的例子中,第一次调用 vsnprintf 时,使用的是 vsnprintf(NULL, 0, format, ap),这种情况下,函数返回的是格式化字符串中需要写入的字符数,但是并没有真正写入任何字符到缓冲区,所以返回值是10。

第二次调用 vsnprintf 时,使用的是 vsnprintf(buf, 3, format, ap)。这次,vsnprintf 会将格式化的字符串写入到缓冲区 buf 中。由于你的格式化字符串是 "say=%d\n",其中 %d 表示一个整数,因此实际的字符串长度会根据你提供的参数(这里是 10000)而变化。因此,你看到的不同返回值(16, 14, 15)可能是由于参数变化导致的。

另外,你的代码中 memset(buf, 0, 200); 这行代码实际上并没有必要。因为 buf 已经被初始化为空字符数组,已经是全0了。如果你想确保缓冲区在格式化字符串之前被清空,那么你可以去掉这行代码,或者改为 buf[0] = '\0'; 以确保缓冲区的首字符是空字符。

总的来说,vsnprintf 的返回值是根据实际写入到缓冲区的字符数而变化的,这取决于你提供的格式化字符串和参数。

 类似资料:
  • 问题内容: 我运行了跟随脚本(java),它给了我奇怪的结果。有人可以帮忙解释吗? 记录结果(彼此不同): - - 背景 - - 我想将自己的keyGenrator用于@Cacheable批注(Spring和ehCache)。 在这种情况下,我发现缓存总是丢失的。 然后,我必须更改为: 谢谢 问题答案: 这是因为for 不会被覆盖。即使条目相同,也没有理由为什么的两个实例应该具有相同的值。 试试这

  • 问题内容: 我正在尝试执行上述程序,但为同一程序提供了不同的值。对于给定的字符串执行多次时,是否有任何方法可以获取相同的字节? 问题答案: 在这里,您不打印a的值。正如owlstead在注释中正确指出的那样,将在字节数组上调用Object.toString()方法。导致这种格式的输出: 如果要打印数组中的每个元素,则必须遍历它。 甚至更简单,请使用以下方法:

  • 为什么gcc在上的末尾插入了,而我却要自己在上添加? 从:

  • 问题内容: 我正在编写一个PHP脚本,用于通过Linux shell命令使用PHP调用它来检查网络连接: 我没有从ping获得错误消息的输出,这是我期望的: 如果该域是一个很好的域,例如yahoo.com,则将ping中的输出输出到数组中。但是,如果这是一个错误,例如它不会返回到数组。 为什么会发生这种情况,有更好的方法吗? 问题答案: 您应该将stderr重定向到stdout。 为此,请像这样更

  • 我为我的密码学初学者水平道歉 在我的项目中,我发现在将密码插入数据库之前需要对密码进行散列,因此我搜索了顶级散列算法,发现了PBKFD2和salt方法。 我这样做的方法是生成随机64char Salt并使用它来散列密码。然后将哈希密码和salt存储在我的数据库中。(注:注册时也会生成密码。这不是我的选择) 登录时,我的Servlet获取密码,然后用数据库中存储的salt散列它。但是我得到了不同的结

  • 问题内容: 问题 我有用于生成哈希的node.js模块。 最近,我注意到模块生成的哈希在新版本中有所不同: 码 Node.js v0.10.0 输出: Node.js v6.1.0 输出: 题 我想知道是什么导致了新版本中的问题,如何解决呢? 更新资料 GitHub上的类似问题: https://github.com/nodejs/node/issues/6813 https://github.c