【问题标题】:sprintf using function as argumentsprintf 使用函数作为参数
【发布时间】:2021-06-25 20:45:52
【问题描述】:

我一直坚持从 const char* 的 c 函数调用和 sprintf 函数中获取一个简单的字符串,该函数有 10 次调用与格式参数相同的函数。但是 sprintf 在调用函数 u 时总是给出最后一个相同的参数值,即:“MM”

main()
 {
  char test[1000];
  int x=sprintf(test,"%s %s",u(17,0),u(18,1));
  printf(test);
 }

const char *u(int a,int b)
{
 static char retStr[700]; 
 static char retStr1[700]; 
 const char *c;
 char *d[]={"S","M","T","W","F"};
 if(b==0) c="red";
 if(b==1) c="blue";

    if(a==17 && b==0) {
        sprintf(retStr1,"<font color=%s>%s</font>",c,d[0]);
        strcpy(retStr,retStr1);
        return retStr;
        } 
    if(a==18 && b==1) {
        sprintf(retStr1,"<font color=%s>%s</font>",c,d[1]);
        strcpy(retStr,retStr1);
        return retStr;
        } 
   return "";
}

【问题讨论】:

  • u(18,) ?这是什么?请发帖minimal reproducible example,并描述这件事应该做什么。
  • 注意,同时标记 C 和 C++ 并没有帮助。 C++ 解决方案只会说废弃所有这些并使用std::string,而 C 解决方案会非常不同。所以选择你想要的。
  • 已更正,仅限 C,代码正在生成 HTML 字符串。一行包含具有 10 个字符串参数的 sprintf,具有相同的函数并返回不同的字符串和颜色。

标签: c


【解决方案1】:

您对函数的两次调用使用相同的缓冲区。

你正在这样做:

  • u(17,0) -> 准备 retStr,返回这个 静态变量
  • u(18,?) -> 覆盖 retStr,返回相同的静态变量
  • 调用sprintf 并使用对同一个retStr 的两个引用,其中现在包含来自u(18,?) 的数据。 *

每次调用函数都需要一个单独的缓冲区。您可以将 u(a, b, buf) 中的缓冲区传递给 strcpy ,或者使用类似 malloc 的东西为函数的每次调用提供缓冲区,并在完成后使用 free 提供缓冲区。

 main()
 {
  char buf1[500], buf2[500]
  char test[1000];
  int x=sprintf(test,"%s %s",u(17,0,buf1),u(18,?,buf2));
  printf(test);
 }

...
const char *u(int a,int b, char *buf)
{
...
     strcpy(buf,retStr1);
...
     return buf;
}

请注意,如果您溢出缓冲区,这里会有很多危险的缓冲区操作,但请展示解决问题的最简单方法。

*:这可能反过来发生。 C 没有指定函数参数出现的顺序。

【讨论】:

  • 附带说明:不能保证u(17,0)u(18,?) 之前被调用。函数参数的求值顺序未指定。
  • 确实如此。它们可以反转,但它们都必须在调用 sprintf 之前发生。从所谓的输出来看,我猜他们是从左到右发生的。添加了一个脚注。
  • 我会试试这个。似乎合乎逻辑,我不是一个经验丰富的人,但很奇怪,为什么主缓冲区不能像文字一样附加每个返回的缓冲区。
  • 在 C 中,参数中的任何函数都必须在外部函数完成之前完成。在函数中使用 sprintf 后,您就不再需要处理文字了。如果您所做的只是return "m"return "s",它会正常工作。但你不是,你在一个缓冲区中构造一个字符串,你一直在重用。它自己很好,但如果你希望它在再次尝试后保持不变,那就不行了。
  • 顺便说一句:标准 Unix (Posix) C 库中有很多函数存在这个问题,必须用带缓冲区的扩展版本替换。比较 strerrorstrerror_r。如果您使用线程和共享缓冲区,这也会分崩离析。
猜你喜欢
  • 2012-06-23
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多