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 / 格式化字符串可以直接传递给函数吗?的主要内容,如果未能解决你的问题,请参考以下文章