CLion无法正确读取TXT文件中中文菜品名的技术求助
问题描述
我是计算机相关专业的中国大学生,正在完成餐厅管理系统大作业。代码完成后发现CLion无法正确读取TXT文件中的菜品名称。
尝试过以下方法均无效:
- 使用
%s输入字符串 - 使用
%49[^,]读取逗号前内容 - 改用
\n读取换行符前内容
已确认TXT文件编码为GBK,CLion项目编码也为GBK,除JSON方式外已尝试多种方法,仍无法通过scanf将TXT内容正确读取到菜单结构体中。
相关代码
版本1(按换行解析)
void loadMenuFromFile(const char *filename) { setlocale(LC_ALL, "zh_CN.GBK"); FILE *file = fopen(filename, "r"); if (file == NULL) { perror("无法打开文件"); return; } // 初始化 itemCount 为 0 char line[100]; // 用于存储读取的整行数据 // 读取文件,直到文件末尾 while (fgets(line, sizeof(line), file)) { printf("读取行: %s\n", line); // 打印读取的行 int result = sscanf(line, "菜品ID: %d\n 名称: %49[^\n]\n 价格: %f\n 成本: %f\n", &menu.items[count].id, menu.items[count].name, &menu.items[count].price, &menu.items[count].cost); if (result == 4) { printf("成功解析: ID=%d, 名称=%s, 价格=%.2f, 成本=%.2f", menu.items[count].id, menu.items[count].name, menu.items[count].price, menu.items[count].cost); count++; // 成功解析后增加 itemCount } else { printf("解析失败,读取行内容: %s\n", line); } } fclose(file); printf("菜单数据已从文件 %s 加载,读取了 %d 个菜品\n", filename, count); }
版本2(按逗号分隔解析)
void loadMenuFromFile(const char *filename) { setlocale(LC_ALL, "zh_CN.GBK"); FILE *file = fopen(filename, "r"); if (file == NULL) { perror("无法打开文件"); return; } // 初始化 itemCount 为 0 char line[100]; // 用于存储读取的整行数据 // 读取文件,直到文件末尾 while (fgets(line, sizeof(line), file)) { printf("读取行: %s\n", line); // 打印读取的行 int result = sscanf(line, "菜品ID: %d, 名称: %49[^,], 价格: %f ,成本: %f", &menu.items[count].id, menu.items[count].name, &menu.items[count].price, &menu.items[count].cost); if (result == 4) { printf("成功解析: ID=%d, 名称=%s, 价格=%.2f, 成本=%.2f", menu.items[count].id, menu.items[count].name, menu.items[count].price, menu.items[count].cost); count++; // 成功解析后增加 itemCount } else { printf("解析失败,读取行内容: %s\n", line); } } fclose(file); printf("菜单数据已从文件 %s 加载,读取了 %d 个菜品\n", filename, count); } void saveMenuToFile(const char *filename){ FILE *file = fopen(filename, "w"); if (file == NULL) { perror("无法打开文件"); return; } // 将菜单项写入文件 for (int i = 0; i < count; i++) { fprintf(file, "菜品ID: %d 名称: %s 价格: %.2f 成本: %.2f", menu.items[i].id, menu.items[i].name, menu.items[i].price, menu.items[i].cost); } fclose(file); printf("菜单数据已保存到文件 %s\n", filename); }
解决方案
核心问题是读写格式不匹配:你的saveMenuToFile写入的是无分隔符的连续文本,但两个loadMenuFromFile分别按换行、逗号分隔解析,完全对应不上。
具体修正步骤:
统一文件读写格式
修改写入函数,让每个菜品占一行,字段用逗号分隔,保证格式可解析:void saveMenuToFile(const char *filename){ FILE *file = fopen(filename, "w"); if (file == NULL) { perror("无法打开文件"); return; } for (int i = 0; i < count; i++) { // 每个菜品一行,字段用逗号分隔,格式和解析串严格对应 fprintf(file, "菜品ID: %d, 名称: %s, 价格: %.2f, 成本: %.2f\n", menu.items[i].id, menu.items[i].name, menu.items[i].price, menu.items[i].cost); } fclose(file); printf("菜单数据已保存到文件 %s\n", filename); }修正解析格式
调整sscanf的格式串,和写入格式完全一致,去掉多余空格:int result = sscanf(line, "菜品ID: %d, 名称: %49[^,], 价格: %f, 成本: %f", &menu.items[count].id, menu.items[count].name, &menu.items[count].price, &menu.items[count].cost);基础细节检查
- 确保
menu.items[count].name的数组大小≥50(%49[^,]需要留一个位置存字符串结束符\0) - 将
setlocale(LC_ALL, "zh_CN.GBK");移到程序入口(比如main函数开头),避免编码处理不一致 - 打印
sscanf的返回值result,快速定位哪个字段解析失败(返回1=仅匹配ID,返回2=匹配ID+名称,以此类推)
- 确保
内容的提问来源于stack exchange,提问作者BreakingBad6
相关产品推荐
相关产品推荐

