C++ 用户输入文件名后读取文本文件从第二行开始的异常问题排查
问题根因
该问题由cin >> filename的输入缓冲区残留换行符导致,和文件读取逻辑无关:cin >> 读取字符串时仅会读取到空白符(空格、换行、制表符等)为止,输入文件名后按下的回车会作为换行符残留在标准输入缓冲区中,后续程序执行流程为:
- 第一次从文件读取第一行内容,正常打印到控制台
- 执行
cin.get()时,直接读取到缓冲区残留的换行符,不需要等待用户输入,直接进入下一轮循环 - 第二次从文件读取第二行内容并打印,此时缓冲区已经没有残留内容,
cin.get()才会阻塞等待用户按回车
视觉上就会出现“直接打印第二行、跳过第一行”的错觉。
修复方案
有两种常用修复方式:
方案1:读取文件名后主动清空缓冲区残留内容
在cin >> filename;后追加一行代码,清空缓冲区到换行符为止的所有内容,需要额外引入<limits>头文件,修改后核心代码如下:
#include <iostream> #include <fstream> #include <string> #include <limits> using namespace std; int main(void) { string filename; cin >> filename; // 清空缓冲区残留的换行符 cin.ignore(numeric_limits<streamsize>::max(), '\n'); ifstream in_file; in_file.open(filename); string line; while (getline(in_file, line)) { cout << line << endl; // 追加换行符保证输出格式正常 cin.get(); } in_file.close(); return 0; }
方案2:统一使用getline读取标准输入
避免混合使用cin >>和getline/cin.get(),直接用getline读取文件名,从根源避免缓冲区残留问题:
#include <iostream> #include <fstream> #include <string> using namespace std; int main(void) { string filename; // 直接用getline读取整行作为文件名 getline(cin, filename); ifstream in_file; in_file.open(filename); string line; while (getline(in_file, line)) { cout << line << endl; cin.get(); } in_file.close(); return 0; }
内容的提问来源于stack exchange,提问作者redsh1rt
相关产品推荐
相关产品推荐

