c - 如何将 printf() 函数与自适应类型一起使用?

标签 c printf

让我解释一下情况: 我有一个 C 结构如下:

typedef struct {
  int *val;
  char *name;
} tStruct;

这个结构可能被填充如下: - 如果“val”值不可用,则 val 可以为 null,否则 val 是一个整数值(可以是负数) - 如果名称不可用,名称可以是空字符串,如果名称可用,则名称可以是填充字符串(此处不是空指针)。

我想写一个日志行如下:

  • 如果 val 无效,则 name 有效(等于 WOOT):

LOG val=# name=WOOT

  • 如果 val 无效,则 name 无效:

LOG val=# name=#

  • 如果 val 有效,则 name 无效:

LOG val=123456 name=#

  • 如果 val 有效,则 name 有效(等于 WOOT):

LOG val=123456 name=WOOT

这意味着我需要使用 printf("val=%s name=%s",...) 或 printf("val=%d name=%s",...) 取决于id 值(以便我可以输出 # 或整数)。当 val 无效时输出伪整数值是不合适的,因为任何有符号或无符号值都是可能的。

有什么想法吗?我希望我可以避免使用以下类型的构造,因为我的结构实际上将包含许多字段,从而产生过多的“if”组合:

if ( (struct.val == NULL ) && ( struct.name ) ) then printf ("val=# name=%");
else if ((struct.val == NULL ) && ( ! struct.name ) ) then printf ("val=# name=#");
else if ...

谢谢

最佳答案

创建一个返回该类型的字符串表示的函数,然后在 printf 中使用它

printf("%s", tStruct_to_string(contents));

请注意,以这种方式使用它可能很困难,除非您的转换函数有一些静态缓冲区。

编辑: 在这里使用单个静态缓冲区是错误的,因为它不适用于多个参数。正如@pmg 所说,接受缓冲区更好,但有缓冲区溢出的风险,因此也许您可以将长度作为参数传递,但现在优雅的解决方案并不像以前那么优雅。所以,你的函数可以返回 malloced char*,但之后你又释放了它,动态分配可能会很慢。 Ufff ... 在 C 中管理字符串相当痛苦。

我现在能想到的最好的方法(但它存在重入问题)是使用静态字符串数组并在每次调用时循环遍历它们。

char* tStruct_to_string(tStruct st)
{
    /* 
     * here assuming no one will call printf 
     * with more than 32 arguments of this type,
     * and assuming length of string 100.
     */ 
    static char strings[32][100];
    static int next = 0;
    int current = next;
    // here you write to strings[current]
    // use s(n)printf for writing to string
    next = (next+1)%32;
    return strings[current];
}

此外,其他答案提供了如何避免重复条件的极好建议。

关于c - 如何将 printf() 函数与自适应类型一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14872043/

相关文章:

c - 从给定格式和未知数量的参数构建字符串

c - 在每第 n 个时间步打印输出

并发访问文件 linux

c - 使用libpq库从PostgreSQL的查询结果中获取(integer[])数组值

c - 如何让printf在循环中只运行一次

C - fprintf() & printf() 删除数组元素内存

c - C中通过socket接收和发送数据

c - 如何从c中的另一个结构访问指向一个结构的双指针

c - 在 C 中反转字符串中的单词

c - printf() 似乎没有按预期工作