gpt4 book ai didi

c - printf 和转换 float 参数

转载 作者:行者123 更新时间:2023-12-04 09:46:06 25 4
gpt4 key购买 nike

作为我程序的一部分,我使用:

int ret = vprintf (format, args);

args我进入堆栈,但我不知道堆栈上实际压入的是什么。格式是字符串,我可以读取。

上述方法一直有效,直到我必须打印 float 。当我打印 float 时,我得到一些奇怪的数字......

我检查过如果我调用 float fArg = *(reinterpret_cast<const float*>(args) - 然后打印 fArg打印出正确的值(我在 args 仅由一个实际参数组成时尝试过)

所以我可能需要对 "%...f" 进行特殊处理子格式 - 应转换相应的(子)参数浮。 (... 符号表示可以在 f 之前添加精度、宽度等)我该如何实现?

最佳答案

请注意,对于可变长度参数列表,所有 float 值都被提升为(并作为)double 值。你不能可靠地使用:

float f = va_arg(args, float);  /* BAD! */

因为该语言从不将浮点值放在堆栈上。你必须写:

float f = va_arg(args, double);  /* OK */

这可能是您的全部问题。


如果没有,您可能需要扫描格式字符串,隔离格式说明符,并实现核心 printf() 代码的重要部分。对于每个说明符,您可以从 args 中收集适当的值。然后,您只需使用正确的值对格式字符串的初始段(因为您无法修改原始段)的副本调用适当的 printf() 函数。对于你的特殊情况,你可以做任何你需要做的不同的事情。

如果能够将 args 参数传递给 vprintf() 就好了,这样它就可以处理收集类型等问题,但我认为这不是便携(这无疑是一件麻烦事)。在将 va_list 值(例如 args)传递给使用 va_arg() 的函数后,除了va_end() 函数返回后的值。


今年早些时候,我为 POSIX 增强格式字符串编写了一个 printf() 风格的格式字符串分析器(它支持 n$ 符号来指定哪个参数指定一个特定的值)。我创建的 header 包含(以及 PFP_ErrnoPFP_StatusFWP_NoneFWP_Star 的枚举):

typedef struct PrintFormat
{
const char *start; /* Pointer to % symbol */
const char *end; /* Pointer to conversion specifier */
PFP_Errno error; /* Conversion error number */
short width; /* Field width (FPW_None for none, FPW_Star for *) */
short precision; /* Field precision (FPW_None for none, FPW_Star for *) */
short conv_num; /* n of %n$ (0 for none) */
short width_num; /* n of *n$ for width (0 for none) */
short prec_num; /* n of *n$ for precision (0 for none) */
char flags[6]; /* [+-0# ] */
char modifier[3]; /* hh|h|l|ll|j|z|t|L */
char convspec; /* [diouxXfFeEgGAascp] */
} PrintFormat;

/*
** print_format_parse() - isolate and parse next printf() conversion specification
**
** PrintFormat pf;
** PFP_Status rc;
** const char *format = "...%3$+-*2$.*1$llX...";
** const char *start = format;
** while ((rc = print_format_parse(start, &pf)) == PFP_Found)
** {
** ...use filled in pf to identify format...
** start = pf.end + 1;
** }
** if (rc == PFP_Error)
** ...report error, possibly using print_format_error(pf.error)...
*/
extern PFP_Status print_format_parse(const char *src, PrintFormat *pf);
extern const char *print_format_error(PFP_Errno err);
extern PFP_Status print_format_create(PrintFormat *pf, char *buffer, size_t buflen);

parse 函数分析源代码并在结构中设置适当的信息。 create 函数接受一个结构并创建相应的格式字符串。请注意示例中的转换说明符 (%3$+-*2$.*1$llX) 是有效的(但有点可疑);它转换作为参数 3 传递的 unsigned long long 整数,宽度由参数 2 指定,精度由参数 1 指定。您可能有更长的格式,但只有几个字符没有重复,即使您总共使用了数十或数百个参数。

关于c - printf 和转换 float 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8114834/

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