2

我有一个格式字符串char *format = "hello %d world %d"和一个数组int array[2] = {10, 20};。这只是为了举例,要在数组中打印的值的数量可以是任意的,一个最大大小的数组,其中包含要打印的值的数量。( int array[MAX]; int array_count)。

所以很明显我不能使用这个标准prinf(format, ..)。所以我想的是,我将遍历格式字符串,并从中提取一个只有一个格式说明符的子字符串,然后使用printf(sub-string, array[index]);子字符串并将其推进到下一个格式说明符——就像 printf 在内部所做的那样。

所以我很想知道是否有任何给定打印格式字符串的库将返回该字符串中第一个格式说明符的偏移量,以便为我节省一些工作?

4

2 回答 2

0

我有一个。不过在这里发帖有点大。通过电子邮件与我联系 - 查看我的个人资料。

这是标题,因此您对要进入的内容有所了解:

/*
@(#)File:           $RCSfile: printfmt.h,v $
@(#)Version:        $Revision: 2.1 $
@(#)Last changed:   $Date: 2011/07/18 16:30:54 $
@(#)Purpose:        Parse printf() format string for conversion specification
@(#)Author:         J Leffler
@(#)Copyright:      (C) JLSS 2011
@(#)Product:        :PRODUCT:
*/

/*TABSTOP=4*/

#ifndef JLSS_ID_PRINTFMT_H
#define JLSS_ID_PRINTFMT_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>

#ifdef MAIN_PROGRAM
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
extern const char jlss_id_printfmt_h[];
const char jlss_id_printfmt_h[] = "@(#)$Id: printfmt.h,v 2.1 2011/07/18 16:30:54 jleffler Exp $";
#endif /* lint */
#endif /* MAIN_PROGRAM */

typedef enum PFP_Errno
{
    PFE_NoError,            /* No error */
    PFE_InvalidFormat,      /* Found % with no valid conversion specifier */
    PFE_NumberOverflow,     /* Number too big (max: 16,383) (should not be seen by users) */
    PFE_WidthOverflow,      /* Field width too big (max: 16,383)     */
    PFE_PrecOverflow,       /* Field precision too big (max: 16,383) */
    PFE_InvalidModifier,    /* Invalid modifier characters */
    PFE_MissingNDollar,     /* One n$ was present and others were missing */
    PFE_RepeatedFlag,       /* One of the flags was repeated */
    PFE_DollarOverflow,     /* Value in n$ too big (max: 16,383) */
    PFE_InvalidError,       /* Error number is not recognized */
    PFE_BufferTooSmall,     /* Buffer too small */
    PFE_BogusWidth,         /* Faulty width specification */
    PFE_BogusPrecision,     /* Faulty precision specification */
} PFP_Errno;

enum
{
    FWP_None   = -1,
    FWP_Star   = -2,
};

typedef enum PFP_Status
{
    PFP_Found  = +1,
    PFP_Error  = -1,
    PFP_Finish =  0,
} PFP_Status;

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);

#ifdef __cplusplus
}
#endif

#endif /* JLSS_ID_PRINTFMT_H */
于 2012-02-10T05:55:40.663 回答
0

好吧,printf-parse的 GNU libc 实现是开源的。您必须确保许可适合您的项目。

另一种选择是使用外部函数接口库来使用动态数量的参数进行函数调用。avcall应该允许这样做,并且可能也可以使用libffi来完成。

于 2012-02-10T05:56:43.543 回答