首页 > 解决方案 > 如何从文件以及 std::cin 中读取行?

问题描述

我正在编写一个程序,它从文件中获取要使用的文本行,用户将其名称作为参数传递,例如program <name of the file>. 但如果未提供名称,则输入从std::cin. 我试过的:

  1. 重定向缓冲区(为什么会导致段错误)
if (argc == 2) {
    std::ifstream ifs(argv[1]);
    if (!ifs)
        std::cerr << "couldn't open " << argv[1] << " for reading" << '\n';
    std::cin.rdbuf(ifs.rdbuf());
}

for (;;) {
    std::string line;
    if (!std::getline(std::cin, line)) // Here the segfault happens 
        break;
  1. 创建一个变量,其中存储输入源
std::ifstream ifs;
if (argc == 2) {
    ifs.open(argv[1]);
    if (!ifs)
        std::cerr << "couldn't open " << argv[1] << " for reading" << '\n';
} else
    ifs = std::cin;  // Doesn't work because of the different types

for (;;) {
    std::string line;
    if (!std::getline(ifs, line))
        break;

现在我正在考虑用文件结构/描述符做一些事情。该怎么办?

UPD:我希望能够在程序的主循环中更新输入源(见下文)。

标签: c++

解决方案


第一个示例中的段错误是由于指针悬空造成的;在你打电话后std::cin.rdbuf(ifs.rdbuf())ifs被摧毁。你应该按照@NathanOliver 的建议做,并编写一个函数,它需要一个istream&

#include <iostream>
#include <fstream>
#include <string>

void foo(std::istream& stream) {
  std::string line;
  while (std::getline(stream, line)) {
    // do work
  }
}

int main(int argc, char* argv[]) {
  if (argc == 2) {
    std::ifstream file(argv[1]);
    foo(file);
  } else {
    foo(std::cin);
  }
}

推荐阅读