C语言switch case调用文件存储函数时多词输入重复弹菜单问题
C语言文件写入功能异常排查
问题根因
两个异常的触发点都和标准输入读取逻辑、文件IO操作不规范有关:
- 文件无有效写入内容的原因
- 写文件流程未闭环:第一次以
w模式打开文件完成fprintf写入后,没有执行fclose()关闭文件句柄,写入的内容停留在C库IO缓冲区没有刷新到磁盘,就直接重新以读模式打开同一文件,旧的写模式文件指针被覆盖造成资源泄漏,内容无法落盘。 - 原代码写入和读取文件都使用
scanf("%s")/fscanf("%s"),本身只能读取到第一个空白符前的内容,即使写入成功也只能读到第一个单词,容易造成“没写进去”的误判。 - 原
store_file函数定义返回值为void,末尾写了return 0;存在语法错误,部分编译器会直接编译失败。
- 写文件流程未闭环:第一次以
- 多单词输入触发菜单反复弹出的原因
scanf("%s")的读取规则是遇到任意空白字符(空格、换行、制表符)就终止读取。当输入带空格的整句文本时,第一次scanf("%s")仅会读取第一个单词,剩余所有内容全部残留在标准输入缓冲区。等store_file执行完回到菜单循环,下一轮scanf("%d",&choice)尝试从缓冲区读整数时,读到非数字内容就会匹配失败,既不会修改choice变量的值,也不会清空缓冲区残留内容,导致循环反复触发、菜单不断重绘。
额外注意:scanf("%s", text)不需要对数组名text取地址,数组名本身就代表数组首元素地址,额外加&属于语义错误。
修复方案
- 所有IO操作完成后必须及时关闭文件句柄:写操作完成立刻
fclose关闭写模式句柄,确保缓冲区内容刷新到磁盘后,再重新打开文件做读取验证。 - 替换整行文本读取逻辑:弃用
scanf("%s")读取可能包含空格的文本,改用fgets()读取整行输入,同时手动处理fgets读入的末尾换行符。 - 增加输入缓冲区清理逻辑:每次用
scanf读取菜单选项后,立刻清空缓冲区中残留的换行、无效字符,避免残留内容干扰后续输入读取。 - 修正语法错误:去掉
void类型store_file函数末尾的无效return 0;。
修复后可运行代码
#include <stdio.h> #include <stdlib.h> #include <string.h> void store_file(); void menu(); void menu(){ int choice; printf("\n\n\t\tfile learning\n\n\n"); while(1) { printf("1. Store the file \n"); printf("2. Test 2\n"); printf("3. Quit\n"); printf("Enter your choice:"); scanf("%d",&choice); // 清空输入缓冲区残留内容 while(getchar() != '\n'); switch(choice) { case 1: printf("\n\n\n\n\n"); store_file(); break; case 3: exit(0); default: printf("Invalid choice, please input again.\n"); } } } void store_file(){ char text[50]; FILE *fptr; fptr = fopen("program.txt","w"); if(fptr == NULL) { printf("Error opening file for write!"); exit(1); } printf("Enter your text: "); // 读取整行输入,支持带空格的文本 fgets(text, sizeof(text), stdin); // 去掉fgets读入的末尾换行符 char *newline_pos = strchr(text, '\n'); if(newline_pos != NULL){ *newline_pos = '\0'; } fprintf(fptr,"%s",text); // 写完立刻关闭写句柄,刷新缓冲区 fclose(fptr); printf("Your file has successfully been created. \n"); if ((fptr = fopen("program.txt","r")) == NULL){ printf("Error! opening file for read"); exit(1); } // 读取整行写入的内容 fgets(text, sizeof(text), fptr); printf("Text in file = %s\n", text); fclose(fptr); } int main(){ menu(); return 0; }
修复后输入包含多个单词的整句文本可以完整写入文件,也不会出现菜单反复弹出的问题,写入完成后可以正常读取文件内的全部内容验证。
内容的提问来源于stack exchange,提问作者MrNate
相关产品推荐
相关产品推荐

