使用fprintf无法写入GLib SList内容到文件的问题
问题分析与解决
核心问题:回调函数参数不匹配
你的代码存在两个关键问题,均因错误地将fprintf/g_fprintf直接作为g_slist_foreach的回调函数导致:
1. 文件仅输出"1",无后续内容
g_slist_foreach要求的回调函数(GFunc)签名为:
void (*GFunc)(gpointer element_data, gpointer user_data);
而fprintf的签名是:
int fprintf(FILE *stream, const char *format, ...);
两者参数顺序、类型完全不兼容:你传递的fprintf会把SList的元素当作FILE*指针,把NULL当作格式字符串调用,完全无法实现打印SList内容的预期效果。
2. 使用g_fprintf触发断言错误
g_fprintf的签名是:
gint g_fprintf(FILE *stream, const gchar *format, ...);
同样与GFunc签名不匹配,调用时format参数被传入NULL,触发了GLib的format != NULL断言检查,导致错误。
修正方案
需要自定义一个适配GFunc签名的回调函数,专门处理SList元素的打印,再将文件指针通过user_data传递给回调:
步骤1:编写SList元素打印回调
根据SList中存储的元素类型调整格式符,以下示例假设元素是字符串:
void print_slist_item(gpointer item, gpointer user_data) { FILE* output_file = (FILE*)user_data; // 若存储的是整数,替换为 "%d " fprintf(output_file, "%s ", (gchar*)item); }
步骤2:修改原fprint函数
修复文件操作逻辑,使用自定义回调遍历SList:
void fprint(gpointer key, gpointer value, gpointer data){ // 若需要追加内容,将"w"改为"a" FILE* op = fopen("Output.txt", "w"); // 增加文件打开失败的错误检查 if (!op) { g_warning("无法打开输出文件"); return; } fprintf(op, "1 "); // 传递文件指针作为user_data给自定义回调 g_slist_foreach((GSList *)value, print_slist_item, op); fprintf(op, "\n"); fclose(op); }
额外注意事项
- 如果SList存储的是整数、结构体等非字符串类型,务必修改
print_slist_item中的格式符和类型转换,确保匹配元素实际类型。 - 每次调用
fprint都会用"w"模式打开文件,这会清空原有内容;如果需要追加内容,改为"a"模式。
内容的提问来源于stack exchange,提问作者simantunes008
相关产品推荐
相关产品推荐

