C中fprintf的通用参数
我正在编写一个函数,使用fprintf函数将数据保存到C中的文件中。 但是,这需要占位符作为其参数之一。 例如:%s表示字符串,%d表示整数…如果数据类型是通用的,我该怎么办,也就是说,使用此函数的程序员可以将我写入文件的变量的数据类型设置为任何内容他要? 谢谢!
您可以使用w+
打开文件,以便以二进制格式写入数据
然后你可以使用fwrite()
直接以二进制forms写入数据,以便稍后由fread()
读取。
由于数据类型仅在运行时已知,因此您必须:
-
生成fprintf函数在运行时使用的格式字符串,或
-
在多个带编码的格式字符串之间进行选择以传递给fprintf。
这两个选项之间的选择可能取决于您必须处理多少种不同类型,和/或您在运行时如何知道占位符参数的类型。
可以尝试以下内容:
在编写时使用struct
来了解数据类型
typedef enum { String, Int, Char} datatype; struct record{ datatype dt; void* data; }; int myfprintf(FILE* stream, struct record* rec){ switch(rec->dt){ case Char: return fprintf(stream, "%c", *((char*)(rec->data))); case Int: return fprintf(stream, "%d", *((int*)rec->data)); case String: return fprintf(stream, "%s", (char*)rec->data); //.... default: return fprintf(stream,"%s", "Error"); } }
然后使用myprintf
传递流和类型record
的数据
或者,您也可以以类似的方式使用union
使用C11
您可以执行以下操作: – (取自此处 ):
#define printf_dec_format(x) _Generic((x), \ char: "%c", \ signed char: "%hhd", \ unsigned char: "%hhu", \ signed short: "%hd", \ unsigned short: "%hu", \ signed int: "%d", \ unsigned int: "%u", \ long int: "%ld", \ unsigned long int: "%lu", \ long long int: "%lld", \ unsigned long long int: "%llu", \ float: "%f", \ double: "%f", \ long double: "%Lf", \ char *: "%s", \ void *: "%p") #define fprint(stream, x) fprintf(stream,printf_dec_format(x), x) fprint(stdin,(char *)"P0W"); // for string literal
C不支持generics,除非在void *我想,我一直在研究一个让C有点Generic的小项目..你可以通过设置类型的一个参数来做你想做的事情,比如0表示字符串和1对于整数
然后制作一个if-else语句,然后单独使用printf。
int print(FILE f,void * x,int type) { 如果(类型== 0) return fprintf(f,“%s”,(char *)x); 其他 return fprintf(f,“%d”,*(int *)x); }
C没有通用数据类型,因此必须创建一个。
typedef enum { Generic_int, Generic_float, Generic_double, Generic_string } Generic_Type; typedef struct { Generic_Type type; union { int i; float f; double d; char *s; // other types } u; } Generic; void Generic_printf(Generic *G) { switch (G->type) { case Generic_int: printf("%d", G->ui); break; case Generic_float: printf("%.*e", FLT_DECIMAL_DIG, G->uf); break; case Generic_double: printf("%.*e", DBL_DECIMAL_DIG, G->ud); break; case Generic_string: printf("\"%s\"", G->us); // Enclose string in quotes break; // other } }