【发布时间】:2013-09-25 15:29:53
【问题描述】:
我正在尝试创建一个函数,它接受可变数量的 std::string 参数并用它格式化字符串。
例子:
Test::formatLine(const string::format, ...)
{
const std::string buffer;
va_list args;
va_start(args, format);
vsprintf(buffer.c_str, format.c_str, args);
va_end(args);
cout << buffer << endl;
}
编译这个sn-p错误:
Error 1 error C3867: 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str': function call missing argument list; use '&std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str' to create a pointer to member
我想要达到的目标:
Test t = Test();
t.formatLine("Hello %s!", "monsieur");
应该打印Hello monsieur!
t.formatLine("Hello %s %s! How %s you today?", "good", "sir", "are");
应该打印Hello good sir! How are you today?
是否可以仅将va_list 和vsprintf 与std::string 一起使用,避免使用char buffer[size]?
Igor 建议修复的工作示例(到目前为止),使用缓冲区:
void Test::formatLine(string format, ...)
{
char buffer[256];
va_list args;
va_start(args, format);
vsprintf_s(buffer, format.c_str(), args);
va_end(args);
cout << buffer << endl;
}
使用 Igor Tandetnik 的建议和示例代码,我终于得到了一个不使用 char buffer[size] 的工作示例:
void Test::formatLine(string format, ...)
{
vector<char> buf(256);
va_list args;
va_start(args, format);
vsnprintf_s(&buf[0], buf.size(), buf.size() + strlen(format.c_str()), format.c_str(), args);
va_end(args);
cout << &buf[0] << endl;
}
【问题讨论】:
-
只允许将琐碎的类型传递给
...,std::string没有这种类型。 -
@Xeo 但是他在他的例子中只传递了一些琐碎的类型 :) 当然,你是对的,如果你把例子改成
t.formatLine("Hello %s!", std::string("monsieur"));,这将非常失败 -
只要生成的字符串适合 256 个字符,您的“工作示例”就很好。此外,它使用的是 Microsoft 特定的、不可移植的
vsprintf_s函数;这可能对您来说是一个问题,也可能不是。 -
为什么是
buf.size() + strlen(format.c_str())?这没有任何意义。我建议你将_TRUNCATE作为vsnprintf_s的第三个参数传递。当然,如果结果字符串长于 256 个字符,您仍然会遇到问题。 -
我正在尝试使生成的字符串大小动态化——出于好奇——现在 256 对我来说应该绰绰有余了。不可移植的功能不是问题。
标签: c++11 stdstring variadic-functions printf