C++如何实现从文件和std::cin两种来源读取文本行?
问题原因分析
- 第一个方案段错误的根本原因是
std::ifstream ifs定义在if分支的局部作用域内,离开if块后ifs会自动析构,你提前绑定到std::cin的缓冲区指针也随之失效,后续调用getline访问悬空指针就会触发段错误。 - 第二个方案编译失败是因为
std::cin的类型是std::istream,std::ifstream是std::istream的子类,两者类型不匹配,不能直接赋值。
实现方案
核心思路是利用多态特性,用std::istream基类指针统一处理不同输入源,同时保证流对象的生命周期覆盖整个使用周期,天然支持动态切换输入源。参考实现代码如下:
#include <iostream> #include <fstream> #include <string> int main(int argc, char* argv[]) { // 保存std::cin原生缓冲区,避免切换或退出时出现未定义行为 const auto original_cin_buf = std::cin.rdbuf(); // 当前输入源,默认指向标准输入 std::istream* current_in = &std::cin; // 存储文件输入流,生命周期和主程序一致,避免局部析构导致悬空 std::ifstream file_stream; // 初始化输入源 if (argc == 2) { file_stream.open(argv[1]); if (!file_stream.is_open()) { std::cerr << "couldn't open " << argv[1] << " for reading" << '\n'; return 1; } current_in = &file_stream; } // 主循环 for (;;) { std::string line; if (!std::getline(*current_in, line)) { // 示例逻辑:当前输入源读取结束,切换到标准输入 if (current_in != &std::cin) { file_stream.close(); current_in = &std::cin; std::cout << "已切换到标准输入" << '\n'; continue; } // 标准输入也读取结束,退出循环 break; } // 此处添加你的行处理逻辑 std::cout << "读取行内容: " << line << '\n'; } // 退出前恢复标准输入的原始缓冲区 std::cin.rdbuf(original_cin_buf); if (file_stream.is_open()) { file_stream.close(); } return 0; }
动态切换输入源说明
你可以在主循环的任意位置修改current_in指针的指向实现输入源切换:
- 切换到新文件:先关闭已打开的
file_stream,调用file_stream.open(新文件路径),打开成功后将current_in = &file_stream即可 - 切换回标准输入:直接将
current_in = &std::cin即可
内容的提问来源于stack exchange,提问作者nuts_eater
相关产品推荐
相关产品推荐

