【发布时间】:2010-11-30 15:53:04
【问题描述】:
在 C++ 中允许这样的事情吗?如果是这样,我该怎么做?
myFunction("User input: %s", a);
还是只有先格式化再通过?
【问题讨论】:
在 C++ 中允许这样的事情吗?如果是这样,我该怎么做?
myFunction("User input: %s", a);
还是只有先格式化再通过?
【问题讨论】:
如果你想写一个带可变参数的函数,答案是肯定的,下面是你如何声明这样一个函数:
void myFunction(const char*, ...);
注意最后的省略号。
但既然你知道如何做到这一点,我会为你把事情复杂化。您不应该这样做。上面声明的myFunction() 是类型不安全的,并且完全回避了 C++ 保护您免受错误的所有手段。
还有其他方法可以完成这样的事情(我想到了vector),但我发现如果你需要一个接受可变参数的函数,这是一种代码味道,表明存在一些问题你的设计放在首位。仔细看看为什么你需要这个。
如果您尝试做的不是传递变量参数本身,而是一个格式化的字符串(就像您的 OP 所说的那样),那么您需要在函数中自己进行字符串格式化。根据您的平台,有多种方法可以做到这一点。在 Windows 中,您可能会使用 vsprintf() 或类似的东西。
但同样,如果您需要这样做,还有更好的方法。我个人喜欢使用Boost format。
【讨论】:
sprintf 不是一个类型——它是一个函数。
我猜你想要的是从你的 myFunction 调用像 vsprintf 这样的函数——这样你就可以在你的函数内部进行格式化。示例:
void myFunction(const char *format, ...)
{
char buf[1024];
va_list arglist;
va_start( arglist, format );
vsprintf(buf,format,arglist);
va_end( arglist );
}
做你正在做的事情是合法的,除了:
sprintf 的行为是将格式应用于字符串。在该函数之外(以及一般的 printf 系列),您在此处的参数并没有真正的“意义”,因为您的函数签名可能如下所示:
void myFunction(const char* str1, const char* str2);
但它做什么取决于你。
如果您想在将字符串传递给某个函数之前对其进行修改,则必须在myFunction 之外修改它(通过sprintf 或其他方式),或者将所有参数传入并在函数内部调用sprintf。
【讨论】:
是的,这是允许的。不,它不是标准库的一部分,所以你必须自己实现它。
【讨论】:
可以使用 C 库中的 vsprintf() 函数,并将 myFunction() 编写为接受可变参数。
但是,关于可变参数方法的常见免责声明适用:以这种方式很容易引入缓冲区溢出或分段违规。一些编译器允许您将 myFunction() 声明为“类似 printf”,这样您就可以在编译时对参数进行一定程度的检查,但这不是可移植的。
【讨论】: