我正在重写一些代码以兼容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;
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
The format string: action=DoSomething&Val1=%"PRIx32"&Val2=%x
The output string: action=DoSomething&Val1=%"PRIx32"&Val2=1
Run Code Online (Sandbox Code Playgroud)
您可以看到格式字符串的%"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的%语法的语法,并编写自己的函数来识别它,并将其替换为正在运行程序的体系结构上的内容.
请注意,从安全角度来看,如果从文件加载格式字符串,则控制文件的任何人都会控制程序执行的操作.
还要注意,printf("Number: %llx\n", (unsigned long long) e);几乎总是有效.如果您的编译器的整数类型大于unsigned long long并且您使用它,它只能让您失望.