作为程序的一部分,我使用:
int ret = vprintf (format, args);
Run Code Online (Sandbox Code Playgroud)
在args我得到的堆栈,我不知道到底是什么,压入堆栈。格式是一个字符串,我可以阅读。
在我必须打印浮点数之前,以上方法一直有效。当我打印浮动时,我得到一些奇怪的数字...
我检查了是否调用float fArg = *(reinterpret_cast<const float*>(args)-然后打印fArg正确的值(当args仅由一个实际参数组成时,我尝试了它)
所以可能我需要特殊的"%...f"子格式行为-相应的(sub)参数应强制转换为float。(该...符号表示可以在之前添加精度,宽度等f)。如何实现?
请注意,对于可变长度参数列表,所有float值都将提升为(并作为double值传递)。您不能可靠地使用:
float f = va_arg(args, float); /* BAD! */
Run Code Online (Sandbox Code Playgroud)
因为语言永远不会在栈上放置浮点值。您将必须编写:
float f = va_arg(args, double); /* OK */
Run Code Online (Sandbox Code Playgroud)
这可能是您的整个问题。
如果不是这样,则可能需要扫描格式字符串,隔离格式说明符,并实现核心printf()代码的重要部分。对于每个说明符,您都可以从中收集适当的值args。然后,您只需printf()使用正确的值在格式字符串的初始段的副本上调用适当的函数(因为您不能修改原始字符串)即可。对于您的特殊情况,您需要做不同的事情。
能够将args参数传递给vprintf()它,以便它处理收集类型等问题,这是很好的,但是我不认为这是可移植的(无疑是麻烦的)。将va_list值(例如)传递给args使用该值的函数之后va_arg(),您将无法va_end()对该函数返回后的值进行可靠的操作。
今年早些时候,我printf()为POSIX增强的格式字符串(支持n$表示指定哪个参数指定特定值的表示法)编写了一个-style格式字符串分析器。创建的头我包含(连同枚举的PFP_Errno,PFP_Status,FWP_None和FWP_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);
Run Code Online (Sandbox Code Playgroud)
解析功能分析源并在结构中设置适当的信息。create函数采用结构并创建相应的格式字符串。请注意,示例(%3$+-*2$.*1$llX)中的转换说明符是有效的(但有点可疑)。它将转换unsigned long long为参数3传递的整数,参数3的宽度由参数2指定,精度由参数1指定。即使您使用了数十或数百个字符,也可能具有更长的格式,但只能包含几个字符而无需重复。总论点。