C语言While循环读取文件时,请求用户输入前先迭代两次的问题
问题分析与解决:While循环提前迭代两次的问题
兄弟,我一眼就瞅出你这问题的病根了——你在代码里混用了fscanf和fgets,这俩函数对输入缓冲区的处理逻辑不一样,直接导致了循环提前“跑两步”的诡异现象。
先看看你给出的代码片段:
fp = fopen("questions.txt","r"); fp2 = fopen("answers.txt","w"); char buff[255]; char input[255]; while (fscanf(fp,"%s",buff)!=EOF) { printf(" %s", buff); printf("answer:"); fgets(input,256,stdin); fprintf(fp2,"\n"); fprintf(fp2,"%s",buff); fprintf(fp2,"\n"); // 后面的fprin应该是fprintf(fp2,"%s",input)吧? }
问题根源
当你用fscanf(fp,"%s",buff)读取文件里的问题时,它只会读取到空格或换行符就停止,但它不会把这个换行符从文件缓冲区里吃掉——这个换行符会留在缓冲区里。
等你第一次调用fgets(input,256,stdin)的时候,它会直接读取这个残留的换行符,相当于用户啥都没输入就直接跳过了,然后循环立马进入下一次fscanf读取下一个问题,这就给你造成了“循环在请求输入前先迭代两次”的错觉。
两种解决方案
方案一:在fscanf之后清理输入缓冲区
在调用fgets之前,把文件缓冲区里残留的换行符(以及其他多余字符)全部清掉:
fp = fopen("questions.txt","r"); fp2 = fopen("answers.txt","w"); char buff[255]; char input[255]; while (fscanf(fp,"%s",buff)!=EOF) { printf(" %s", buff); printf("answer:"); // 清理缓冲区里的残留字符,直到遇到换行或文件结束 int c; while ((c = getchar()) != '\n' && c != EOF); fgets(input,256,stdin); fprintf(fp2,"\n"); fprintf(fp2,"%s",buff); fprintf(fp2,"\n"); fprintf(fp2,"%s",input); } // 别忘了关闭文件! fclose(fp); fclose(fp2);
方案二:统一用fgets读取文件内容
干脆放弃fscanf,全程用fgets来处理文件和用户输入,这样就不会有缓冲区冲突的问题了:
fp = fopen("questions.txt","r"); fp2 = fopen("answers.txt","w"); char buff[255]; char input[255]; // 用fgets读取每一行问题 while (fgets(buff, sizeof(buff), fp) != NULL) { // 去掉buff末尾的换行符(避免输出时多出空行) buff[strcspn(buff, "\n")] = '\0'; printf(" %s", buff); printf("answer:"); fgets(input,256,stdin); fprintf(fp2,"\n"); fprintf(fp2,"%s",buff); fprintf(fp2,"\n"); fprintf(fp2,"%s",input); } // 必须关闭文件,否则会有资源泄漏 fclose(fp); fclose(fp2);
这里用strcspn来定位换行符的位置,然后把它替换成字符串结束符\0,这样输出的问题就不会带着多余的换行啦。
另外提个小细节:你的代码里没写fclose,记得一定要加上,不然打开的文件句柄不会被正常释放,容易出问题。
内容的提问来源于stack exchange,提问作者Toxicology Overload
相关产品推荐
相关产品推荐

