C语言if语句下输入被跳过问题求助(无if时功能正常)
问题:scanf读取整数后fgets跳过输入的解决办法
我写了一个C程序,让用户选择1(创建文件)或2(追加文件),但运行时if (opt == 1)分支里,程序会跳过文件名的输入步骤。
期望输出:
Enter a file name: (input)
Enter file contents: (input)
实际输出:
Enter a file name: Enter file contents: (input)
原代码:
#include <stdio.h> int main(void) { char fname[20]; char fcontents[250]; int opt; printf("Make a file(1),Append a file(2)"); scanf("%d", &opt); if (opt == 1) { printf("Enter a file name: "); fgets(fname, 20, stdin); printf("Enter file contents: "); fgets(fcontents, 250, stdin); FILE* fpointer = fopen(fname, "w"); fprintf(fpointer, "%s", fcontents); fclose(fpointer); printf("FILE: %s successfully created", fname); } else if (opt == 2) { printf("Enter a file name: "); fgets(fname, 20, stdin); printf("Enter file appends: "); fgets(fcontents, 250, stdin); FILE* fpointer = fopen(fname, "a"); fprintf(fpointer, "%s", fcontents); fclose(fpointer); printf("FILE: %s successfully created", fname); } }
问题原因
问题出在scanf("%d", &opt);这行:当你输入数字后按回车,输入缓冲区里会残留一个换行符,scanf只读取了数字,没处理这个换行符。后续调用fgets时,它会直接读取这个换行符,误以为已经完成了文件名的输入,于是跳过了用户手动输入的步骤。
另外还有个隐藏问题:fgets会把换行符也读进字符串里,比如输入test.txt回车后,fname里会是test.txt\n,这会导致fopen找不到目标文件。
解决方案
方法1:用getchar清除缓冲区换行符
在scanf之后加一行getchar(),吃掉残留的换行符:
printf("Make a file(1),Append a file(2): "); scanf("%d", &opt); getchar(); // 清除输入缓冲区的换行符
方法2:在scanf格式串中处理空白字符
修改scanf的格式,让它自动忽略换行、空格等空白字符:
// 用\n跳过换行 scanf("%d\n", &opt); // 或者用空格跳过所有空白字符 scanf("%d ", &opt);
方法3:统一用fgets读取输入再转整数
避免混用scanf和fgets,先读取整行输入,再用sscanf转成整数:
char opt_str[10]; printf("Make a file(1),Append a file(2): "); fgets(opt_str, 10, stdin); sscanf(opt_str, "%d", &opt);
附加处理:去掉fgets读取的换行符
不管用哪种方法,都建议给fgets读取的字符串去掉换行符,避免文件打开失败:
// 需要包含string.h头文件 fname[strcspn(fname, "\n")] = '\0';
完整修改后的代码(以方法1为例)
#include <stdio.h> #include <string.h> // 用于strcspn函数 int main(void) { char fname[20]; char fcontents[250]; int opt; printf("Make a file(1),Append a file(2): "); scanf("%d", &opt); getchar(); // 清除缓冲区的换行符 if (opt == 1) { printf("Enter a file name: "); fgets(fname, 20, stdin); fname[strcspn(fname, "\n")] = '\0'; // 去掉换行符 printf("Enter file contents: "); fgets(fcontents, 250, stdin); FILE* fpointer = fopen(fname, "w"); if (fpointer != NULL) { // 检查文件是否成功打开 fprintf(fpointer, "%s", fcontents); fclose(fpointer); printf("FILE: %s successfully created\n", fname); } else { printf("Failed to open file %s\n", fname); } } else if (opt == 2) { printf("Enter a file name: "); fgets(fname, 20, stdin); fname[strcspn(fname, "\n")] = '\0'; // 去掉换行符 printf("Enter file appends: "); fgets(fcontents, 250, stdin); FILE* fpointer = fopen(fname, "a"); if (fpointer != NULL) { // 检查文件是否成功打开 fprintf(fpointer, "%s", fcontents); fclose(fpointer); printf("FILE: %s successfully appended\n", fname); } else { printf("Failed to open file %s\n", fname); } } else { printf("Invalid option\n"); } return 0; }
内容的提问来源于stack exchange,提问作者user18326065
相关产品推荐
相关产品推荐

