我有一个如下的printf语句:
printf("[%d] %d", i, n->data);
我正在努力使相关代码变得灵活,因此您可以根据需要更改“n->数据”的变量类型。有没有办法根据使用的变量类型更新格式说明符?
我尝试过包括:
const char FS[2] = "%f";
当变量是float时,然后将printf语句修改为:
printf("[%d] "FS, i, n->data);
但是这会出现以下错误,我不知道如何解决:
dLList.c:125:23: error: expected ')'
printf("[%d] "FS, i, n->data);
^
dLList.c:125:15: note: to match this '('
printf("[%d] "FS, i, n->data);
^
1 error generated.
有什么想法吗? 感谢
答案 0 :(得分:3)
而不是const char FS[2] = "%f";
,您可以尝试使用这样的宏:
#define FS "%f"
会聚合你想要的控制字符串格式。
答案 1 :(得分:3)
有没有办法根据使用的变量类型更新格式说明符?
是的,C11有_Generic
。这允许基于表达式的类型进行代码选择。选择不在运行时进行评估,但在编译时,将确定类型。
#include <stdio.h>
#include <stdlib.h>
#define print(X) printf(_Generic((X), \
double: "%e\n", \
int: "%i\n", \
char *: "%s\n", \
default: "TBD" \
) , X)
int main(void) {
print(5.0);
print(5);
print("Five");
print(1.0f);
return 0;
}
输出
5.000000e+00
5
Five
TBD
答案 2 :(得分:0)
您可以使用枚举和查找表格式化字符串。 只需确保包含数据的结构也包含一个匹配的枚举,用于描述结构中当前包含的数据类型。
通过这种方式,您可以编写一个接受这样的结构作为参数的打印函数,并使用该类型数据的正确格式字符串打印其值。
#include <stdio.h>
typedef enum Format_
{
/* Add/remove formats as needed. */
SIGNED_DECIMAL_INT,
UNSIGNED_DECIMAL_INT,
DECIMAL_FLOATING_POINT,
STRING,
POINTER_ADDRESS,
NUM_SUPPORTED_FORMATS
} Format;
static const char* formatStrings[NUM_SUPPORTED_FORMATS] =
{
"%d\n", /* Add more complex format strings if needed. */
"%u\n",
"%f\n",
"%s\n",
"%p\n"
};
typedef struct Wrapper_
{
Format format;
float data;
} Wrapper;
void printData(const Wrapper *const wrapper)
{
printf(formatStrings[wrapper->format], wrapper->data);
}
int main(void)
{
Wrapper wrapper;
wrapper.format = DECIMAL_FLOATING_POINT;
wrapper.data = 12.345f;
/* Prints 12.345000 */
printData(&wrapper);
return 0;
}