Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C vsnprintf与inttypes中宏的兼容性_C_Printf - Fatal编程技术网

C vsnprintf与inttypes中宏的兼容性

C vsnprintf与inttypes中宏的兼容性,c,printf,C,Printf,我正在重写一些代码,以便与32位和64位体系结构兼容,但我遇到了vsnprintf调用的问题。在这两种体系结构上,vsnprintf似乎都不能正确处理inttypes.h中的固定大小整数类型 以下是相关代码: void formatString(char *buffer, int size, char *format, ...) { va_list va; /* Format the data */ va_start( va, format ); vsnprin

我正在重写一些代码,以便与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(“数字:%”PRIx32“…”,arg)

在上面的典型习惯用法中,
“Number:%”“PRIx32”…“
被扩展为,比如说,
“Number:%”“lX”…“
,它通过C语法的特性相当于
“Number:%lX…”

如果需要动态创建格式字符串,请使用
strcat
或其他字符串操作功能。
不要编写与
“Number:%\”PRIx32\“…”等价的代码

请记住,
PRIx32
将扩展为字符串文字,不要编写
“%PRIx32”
,这是没有意义的

编辑:

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

请注意,从安全性的角度来看,如果从文件加载格式字符串,则控制该文件的是谁


还要注意,
printf(“编号:%llx\n”,(无符号长)e)几乎总是有效的。如果编译器的整数类型比
unsigned long long
宽,并且您使用了它,那么这只会让您失望。

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

典型的用法是
printf(“数字:%”PRIx32“…”,arg)

在上面的典型习惯用法中,
“Number:%”“PRIx32”…“
被扩展为,比如说,
“Number:%”“lX”…“
,它通过C语法的特性相当于
“Number:%lX…”

如果需要动态创建格式字符串,请使用
strcat
或其他字符串操作功能。
不要编写与
“Number:%\”PRIx32\“…”等价的代码

请记住,
PRIx32
将扩展为字符串文字,不要编写
“%PRIx32”
,这是没有意义的

编辑:

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

请注意,从安全性的角度来看,如果从文件加载格式字符串,则控制该文件的是谁


还要注意,
printf(“编号:%llx\n”,(无符号长)e)几乎总是有效的。如果编译器的整数类型大于
unsigned long long
,并且您使用它,那么这只会让您失望。

什么是
stringsLookup(0)
?它是一个“char*stringsLookup(int index)”函数,负责从外部资源加载字符串。它将加载的字符串是“action=DoSomething&Val1=%”“PRIx32”&Val2=%x”。这就是我在代码其他地方的printf语句中使用的内容,所以这就是我在这里使用的内容。我之所以问这个问题,是因为这可能是bug所在的地方,但我假设它在我的答案中。我认为该函数会有问题,这就是为什么我打印出它的返回值(格式字符串)。什么是
stringsLookup(0)
?这是一个“char*stringsLookup(int-index)”函数,负责从外部资源加载字符串。它将加载的字符串是“action=DoSomething&Val1=%”“PRIx32”&Val2=%x”。这就是我在代码其他地方的printf语句中使用的内容,所以这就是我在这里使用的内容。我之所以问这个问题,是因为这可能是bug所在的地方,但我去假设它在我的答案中。我想这个函数会有问题,这就是为什么我打印出它的返回值(格式字符串)。@KeithThompson它这样做了,我会再做一次。谢谢你的改进。我不想动态创建字符串。我只想用“PRIx32”而不是