gpt4 book ai didi

vsnprintf 和来自 inttypes 的宏的兼容性

转载 作者:太空宇宙 更新时间:2023-11-04 05:57:54 31 4
gpt4 key购买 nike

我正在重写一些代码以与 32 位和 64 位架构兼容,但我在调用 vsnprintf 时遇到了问题。 vsnprintf 似乎没有在任一架构上正确处理来自 inttypes.h 的固定大小整数类型。

相关代码如下:

void formatString(char *buffer, int size, char *format, ...)
{
va_list va;

/* Format the data */
va_start( va, format );
vsnprintf( (char *)buffer, size, format, va );
va_end( va );
}

int main(int argc, char *argv[])
{
char buffer[2048];

printf("The format string: %s\n", stringsLookup(0));
formatString(&buffer[0], sizeof(buffer), stringsLookup(0), 1, 2);
printf("The output string: %s\n", buffer);

return 0;
}

输出如下:

The format string: action=DoSomething&Val1=%"PRIx32"&Val2=%x
The output string: action=DoSomething&Val1=%"PRIx32"&Val2=1

您可以看到格式字符串的 %"PRIx32"部分没有按预期替换为值“1”。这是一个已知的问题?有变通办法吗?

我会提到,如果我对源代码中的字符串进行硬编码,预处理器似乎会将“%PRIu32”转换为适合架构的宏,并且对 vsnprintf 的调用有效。不幸的是,我需要能够加载字符串。

更新

一些额外的背景:当我从 32 位系统迁移到 64 位系统时,我必须修复某些变量的大小。我将它们声明为 uint32_t。我还更改了打印它们的位置以清除编译器警告。前面的代码使用了 printf("%lx")。我使用了 printf("%"PRIx32)。我需要对 vsnprintf 的调用做类似的事情。

如前所述,如果我在源代码中对字符串进行硬编码,预处理器似乎会将“%”PRIx32 适本地转换为“%lx”或“%x”。不幸的是,当我必须从文件中加载字符串时遇到了麻烦。预处理器无法帮助我。

最佳答案

PRIx32 是一个宏,其名称即使在格式字符串中也不应以文本形式出现。您几乎可以肯定使用错误,除非它扩展为包含 "PRIx32" 的字符串(几乎可以肯定不会)。

典型的用法是 printf("Number: %"PRIx32 "...", arg);

在上面的典型习语中,"Number: %"PRIx32 "..." 被扩展为,比方说,"Number: %""lX""...",根据 C 语法的特性,它等同于 "Number: %lX..."

如果您需要动态创建格式字符串,请使用 strcat 或其他字符串操作函数。 不要写等同于 "Number: %\"PRIx32\"..."

只要记住 PRIx32 扩展为字符串文字,不要写 "%PRIx32",那没有意义。

编辑:

如果您从文件中加载格式字符串,我建议您在 45 分钟前在评论中提供的信息,那么您必须在从中加载文件时进行自己的替换。发明一种类似于 printf 的 % 语法的语法,并编写您自己的函数来识别它并将其替换为适合程序运行的体系结构的内容。

注意,从安全的角度来看,如果你从一个文件加载格式字符串,谁控制了这个文件controls what the program does .

另请注意 printf("Number: %llx\n", (unsigned long long) e); 几乎总是有效。如果您的编译器具有比 unsigned long long 宽的整数类型并且您使用它,它只会让您失望。

关于vsnprintf 和来自 inttypes 的宏的兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23837490/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com