是否有printf的通用转换说明符?

时间:2014-11-04 05:30:31

标签: c printf

我想打印变量值而不指定其类型。

在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 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:9)

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

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

有关详情read this link

答案 2 :(得分:5)

不,printf是所谓的variadic function,这意味着它可以接受任何数量/类型的参数。

经典C中具有可变参数函数的问题(好吧,其中之一)是参数不是类型安全的,即 - 被调用的函数不知道参数的类型

这就是使用格式字符串开始输入变量的原因,printf不知道传递的值是指针,整数还是其他类型,需要查看格式字符串以确定是什么格式以显示值。

遗憾的是,如果格式字符串错误,也会出现错误的可能性,例如说当一个值实际上是一个整数时,某个值就是指向某个东西的指针,程序可能会崩溃(或者更具体地说,导致未定义的行为)从尝试访问非指针值作为指针。

答案 3 :(得分:1)

没有这样的事情。我们必须告诉我们要打印哪种格式的值。