C++为什么在使用空指针时改变StaveFFS格式?

C++为什么在使用空指针时改变StaveFFS格式?,c++,printf,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); } 致电: addBuffe

这是工作的原始代码:

// ...
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中的format参数从%llu更改为%d才能获得正确的值。有人能解释一下为什么会发生这种情况,以及将参数更改为%d是否有问题吗?谢谢

发生这种情况是因为在您的情况下sizeofvoid*==4。通过函数调用将uu int64隐式强制转换为void*。因此,如果使用%llu格式,则会从内存中打印一些垃圾

如果可能,我建议您重写函数:

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

我建议简单一点:

std::ostringstream buffer;

buffer << num;
即使它们对于内部化/定制来说很难实现;对于简单格式,流非常简单。。。和安全。

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


当然,尽管如此,我还是建议您在这里研究更安全的实现。您的addBuffered函数不是可变函数有什么原因吗?您可能会使用vsprintf_s。

可能是因为您的指针是32位的。你依赖于未定义的行为。不要这样做。对指针使用正确的格式说明符。我不明白。你能解释一下为什么你必须使用void**而不仅仅是一个void指针吗?当然问题是,为什么要混合使用模板和不安全的C变量。这很难看:习近平同意。提出你的解决方案。如果它是好的,我会投赞成票。撇开美学不谈,有时使用C变量和C样式格式更简单、更简洁、更方便。谢谢,效果很好,我不需要更改任何现有的代码谢谢,不幸的是我不能在我的情况下使用ostringstream
std::ostringstream buffer;

buffer << num;