最近我遇到了这个函数(用在logger类中)。我理解它它做什么,但我不知道如何:
void Reporter::print( const char* szFormat, ...)
{
// note: m_out is a FILE*
va_list args;
va_start(args, szFormat);
vfprintf( m_out, szFormat, args);
va_end(args);
}
我读了reference,但我还不清楚。最让我烦恼的是,这不能按预期工作。我为最后一个数字得到0,为字符串得到(null),尽管它应该打印一个大于0的数字和一个文件的路径。
案例1:
rep.print( "Values: %08X %08X %08X %08X %08X %08X %d %s\n", val1, val2, val3, val4, val5, val6, source.GetLength(), szPath );
// source.GetLength() returns a size_t, szPath is a const char* and IS indeed a valid string
但是改成它可以正常工作:
案例2:
rep.print( "Values: %08X %08X %08X %08X %08X %08X", val1, val2, val3, val4, val5, val6 );
rep.print( " %d %s\n", source.GetLength(), szPath );
请注意,我正在MSVC ++ 2008下编译。相同的代码在gcc下工作正常(即使是第一种情况)。 Reporter :: print()的实现或我使用函数的方式是否有错误?即使在第一种情况下调用它,我怎样才能确保它能正常工作?为什么它甚至会失败?
答案 0 :(得分:3)
Reporter::print
的代码很好。它所做的只是正确初始化args
以引用变量参数列表,然后将该变量参数列表传递给vfprintf()
,它知道如何处理它。
您的问题很可能是%d
格式说明符(需要int
类型参数)与source.GetLength()
返回的值的类型不匹配(我会猜测可能是size_t
)。如果你知道长度总是适合int
,那么你可以通过强制转换解决它:
..., (int)source.GetLength(), ...
(这是因为编译器不知道作为变量参数列表一部分的预期类型的参数,不像普通的原型函数声明)。