sprintf / 格式化字符串可以直接传递给函数吗?

Posted

技术标签:

【中文标题】sprintf / 格式化字符串可以直接传递给函数吗?【英文标题】:Can sprintf / formatted strings be passed directly to a function? 【发布时间】:2010-11-30 15:53:04 【问题描述】:

在 C++ 中允许这样的事情吗?如果是这样,我该怎么做?

myFunction("User input: %s", a);

还是只有先格式化再通过?

【问题讨论】:

【参考方案1】:

如果你想写一个带可变参数的函数,答案是肯定的,下面是你如何声明这样一个函数:

void myFunction(const char*, ...);

注意最后的省略号。

但既然你知道如何做到这一点,我会为你把事情复杂化。您不应该这样做。上面声明的myFunction() 是类型不安全的,并且完全回避了 C++ 保护您免受错误的所有手段。

还有其他方法可以完成这样的事情(我想到了vector),但我发现如果你需要一个接受可变参数的函数,这是一种代码味道,表明存在一些问题你的设计放在首位。仔细看看为什么你需要这个。

编辑:

如果您尝试做的不是传递变量参数本身,而是一个格式化的字符串(就像您的 OP 所说的那样),那么您需要在函数中自己进行字符串格式化。根据您的平台,有多种方法可以做到这一点。在 Windows 中,您可能会使用 vsprintf() 或类似的东西。

但同样,如果您需要这样做,还有更好的方法。我个人喜欢使用Boost format。

【讨论】:

是的——听起来像是提取方法对象的例子:P 嗯,我想如果格式化是在发送字符串的部分完成的,函数将其作为单个参数接收.. 或者声明函数接收 sprintf 类型。所以看起来我会先格式化然后传递它。 @thorvald:我不确定您所说的“格式化是在发送字符串的部分完成的”是什么意思。你能解释一下吗? 另外,sprintf 不是一个类型——它是一个函数。【参考方案2】:

我猜你想要的是从你的 myFunction 调用像 vsprintf 这样的函数——这样你就可以在你的函数内部进行格式化。示例:

void myFunction(const char *format, ...)

  char buf[1024];

  va_list arglist;
  va_start( arglist, format );
  vsprintf(buf,format,arglist);
  va_end( arglist );

【讨论】:

另见***.com/questions/41400/…【参考方案3】:

做你正在做的事情是合法的,除了:

sprintf 的行为是将格式应用于字符串。在该函数之外(以及一般的 printf 系列),您在此处的参数并没有真正的“意义”,因为您的函数签名可能如下所示:

void myFunction(const char* str1, const char* str2);

但它做什么取决于你。

如果您想在将字符串传递给某个函数之前对其进行修改,则必须在myFunction 之外修改它(通过sprintf 或其他方式),或者将所有参数传入并在函数内部调用sprintf

【讨论】:

【参考方案4】:

是的,这是允许的。不,它不是标准库的一部分,所以你必须自己实现它。

【讨论】:

【参考方案5】:

可以使用 C 库中的 vsprintf() 函数,并将 myFunction() 编写为接受可变参数。

但是,关于可变参数方法的常见免责声明适用:以这种方式很容易引入缓冲区溢出或分段违规。一些编译器允许您将 myFunction() 声明为“类似 printf”,这样您就可以在编译时对参数进行一定程度的检查,但这不是可移植的。

【讨论】:

以上是关于sprintf / 格式化字符串可以直接传递给函数吗?的主要内容,如果未能解决你的问题,请参考以下文章

格式化输出字符串——sprintf

Perl:sprintf函数

sprintf函数的用法

c语言中的sprintf函数?

关于sprintf()

sprintf函数的用法是啥?