我有以下(简化目的)代码,它可以工作:
void log(const string type, const string msg, va_list argp)
{
fprintf(stdout, "[%s] ", type.c_str());
vfprintf(stdout, msg.c_str(), argp);
}
void log_err(const string msg, ...)
{
va_list argp;
va_start(argp, msg);
log("ERROR", msg, argp);
va_end(argp);
}
我会以这种方式使用它:
log_err("test: %d", 5);
但是,如果我想把它移到课堂上:
class Logger {
public:
Logger() {
//
};
void generic(const string type, const string msg, va_list argp) {
fprintf(stdout, "[%s] ", type.c_str());
vfprintf(stdout, msg.c_str(), argp);
};
void error(const string msg, ...) {
va_list argp;
va_start(argp, msg);
this->generic("ERROR", msg, argp);
va_end(argp);
};
};
然后我得到了分段错误。我知道像va宏这样棘手的东西无法在类范围内工作,但我想知道原因。
感谢您的建议!
修改
使用示例:
Logger logger;
logger.error("test", 5);
完整来源:
#include <string>
#include <cstdlib>
#include <cstdarg>
using namespace std;
void log(const string type, const string msg, va_list argp)
{
fprintf(stdout, "[%s] ", type.c_str());
vfprintf(stdout, msg.c_str(), argp);
}
void log_err(const string msg, ...)
{
va_list argp;
va_start(argp, msg);
log("ERROR", msg, argp);
va_end(argp);
}
class Logger {
public:
Logger() {
//
};
void generic(const string type, const string msg, va_list argp) {
fprintf(stdout, "[%s] ", type.c_str());
vfprintf(stdout, msg.c_str(), argp);
};
void error(const string msg, ...) {
va_list argp;
va_start(argp, msg);
this->generic("ERROR", msg, argp);
va_end(argp);
};
};
int main()
{
//log_err("test: %s\n", "str");
Logger logger;
logger.error("test %s", 5);
return 0;
}
我不想让这些方法保持静态,因为在原始使用中我有私有文件描述符,我正在写日志消息;
答案 0 :(得分:3)
错误就在这一行:
logger.error("test %s", 5);
%s
格式说明符用于C样式字符串。 5
不是C风格的字符串。使用:
logger.error("test %s", "5");
或:
logger.error("test %d", 5);
答案 1 :(得分:0)
你有99%的路在那里。变化
void generic(const string type, const string msg, va_list argp)
到
void generic(const string type, const string msg, va_list & argp)
似乎你无法复制列表(没有参考就完成了)
编辑::我上面发布的内容是错误的。第一次通过我只是假设提供了seg故障,没有参考就没有测试。我删除了参考,所有打印都很好。
留给未来的人们。