C ++为什么sprintf_s格式在与void指针一起使用时会改变?

时间:2012-07-05 08:22:27

标签: c++ printf

这是正常工作的原始代码:

// ...
unsigned __int64 num = 57;
sprintf_s(buffer, sizeof(buffer), "%llu", num);

但是,当我尝试将此部分提取到此函数中时:

void addBuffered(void** attributeValue, char* format)
{
    sprintf_s(buffer, sizeof(buffer), format, *attributeValue);
}

致电:

addBuffered((void**)&num, "%d");

我必须将sprintf_s中的格式参数从%llu更改为%d才能获得正确的值。有人可以解释为什么会发生这种情况,以及参数更改为%d是否有问题?谢谢!

3 个答案:

答案 0 :(得分:5)

这是因为您的情况为sizeof(void *) == 4。并且您通过函数调用隐式地将__int64强制转换为void *。因此,如果您使用%llu格式,则会从内存中打印一些垃圾。

我建议你尽可能重写功能:

template <typename T>
void addBuffered(T *attributeValue, char* format)
{
    sprintf_s(buffer, sizeof(buffer), format, *attributeValue);
}

呼叫示例:

addBuffered(&num, "%luu");

答案 1 :(得分:1)

我建议简单说明:

std::ostringstream buffer;

buffer << num;

即使它们在内化/定制方面也很笨重;对于简单的格式化流非常简单......并且安全

答案 2 :(得分:0)

您可以安全地使用%p作为printf类型值的相应void *格式说明符。

当然,话虽如此,我还建议你在这里研究一个更安全的实现。你的addBuffered函数是不是有变量的原因吗?您可以改为使用vsprintf_s