printf有通用的转换说明符吗?

12

我想打印变量的值,而不需要指定它的类型。

在C语言中,我可以这样做:


```c printf("%d", variable); ```

但是在C++中,如果我不知道变量的类型,该怎么办?

int main(int argc, char **argv) {
    int i = 1;
    float f = 0.1;
    char s[] = "s";

    printf("%i\n", i);
    printf("%f\n", f);
    printf("%s", s);
    return 0;
}

但我期望:

int main(int argc, char **argv) {
    int i = 1;
    float f = 0.1;
    char s[] = "s";

    printf("%any_type\n", i);
    printf("%any_type\n", f);
    printf("%any_type", s);
    return 0;
}

问题:C语言中是否有%any_type类型?

4个回答

17

C11 中,您可以编写一个通用函数来打印任何类型的数据,并将自定义类型添加到该函数中。

#define print_any(X) _Generic((X), int: print_int, \
                              default: print_unknown, \
                              float: print_float)(X)

int print_int(int i)
{
  return printf("%d\n", i);
}

int print_float(float f)
{
  return printf("%f\n", f);
}

int print_unknown(...)
{
  return printf("ERROR: Unknown type\n");
}

您也可以像下面所示一样自动化函数生成。

#define GEN_PRINT(TYPE, SPECIFIER_STR) int print_##TYPE(TYPE x) { return printf(SPECIFIER_STR "\n", x);}
GEN_PRINT(int, "%d");
GEN_PRINT(char, "%c");
GEN_PRINT(float, "%f");

使用方法如下:

int main(int argc, char **argv) {
    int i = 1;
    float f = 0.1;
    char s[] = "s";

    print_any(i);
    print_any(f);
    print_any(s);
    return 0;
}

为了摩西的爱,请提供一个示例或更详细地讨论它。:'( - Kick Buttowski
更多关于此内容的信息请参见这里 - M.M
1
@KickButtowski 添加了一点信息。谢谢Matt。 - Gyapti Jain
我不喜欢这个。它太容易忘记你正在编写的内容。这有很多坏处,可能会导致崩溃。特别是,在运行时会失败,而使用常规的 printf 更安全,因为在许多编译器下它会在编译时失败。 - SevenBits
@SevenBits,我不太明白你的意思。你能否详细说明一下容易被忽略的是什么?如果你认为有些类型很容易被忽略,可以考虑在编译的调试模式中添加一些无法通过1/0的内容,例如在print_unknown中。这样,如果你忘记了某个情况,就会遇到失败并单独处理它。printf是可变参数函数,因此编译器可以自由地生成或不生成警告,如果百分比指示符与参数不匹配。 - Gyapti Jain

11

不,你必须提供正确的格式说明符。

在C11中,您可以使用_Generic和宏自动计算正确的格式说明符。但是,您必须重复变量的名称(一次用于计算说明符,一次用于将变量作为参数提供)。

更多细节 请阅读此链接


1
这是作为答案发布的,但它并没有试图回答问题。它可能应该是一个编辑、评论、另一个问题或完全删除。 - Kick Buttowski
@KickButtowski - 这是“问题:C语言中是否有%any_type”的答案,即没有。 - Ed Heal
天哪,我不会发这样的回答。至少,帖子可以提供信息。尝试解释如何格式化以及有哪些选项...多提供一些信息不会伤害任何人。 - Kick Buttowski
@KickButtowski - 除了之前评论中的宗教内容,这个人肯定可以谷歌手册页面。 - Ed Heal
@KickButtowski如果你不喜欢这个答案,那就发表你自己的答案。此外,在我看来,这里已经没有更多可说的了。“如何格式化”与OP提出的问题无关。他的代码表明他已经知道如何格式化。 - M.M

6
不,printf是一种所谓的可变参数函数,这意味着它可以使用任意数量/类型的参数。经典C中可变参数函数的问题(嗯,其中之一)在于参数不具备类型安全性,也就是说-被调用的函数没有关于参数的类型信息。这就是为什么首先要使用格式字符串对变量进行类型化的原因,printf不知道传递的值是指针、整数还是其他类型,并且需要查看格式字符串来确定以何种格式显示该值。不幸的是,这也打开了出现错误的可能性,如果格式字符串错误,例如说将一个值表示为指向某个东西的指针时实际上是整数,程序可能会崩溃(或更具体地说,导致未定义行为),因为试图将非指针值作为指针访问。

@remyabel 谢谢,已添加该信息。 - Joachim Isaksson

1

没有这种东西。我们必须确定打印该值的格式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接