【问题标题】:Return to begining of stream after iterating over it in C++在 C++ 中迭代流后返回到流的开头
【发布时间】:2013-11-14 19:12:11
【问题描述】:

我是这样计算文件行数的

n = count(istreambuf_iterator<char>(file), istreambuf_iterator<char>(), '\n') + 1;

之后我想逐行阅读,但这不起作用,

while (!file.eof()) {
    string row;

    file >> row;
    cout << row << endl;
}

因为我认为计数将位置移到了末尾。如果我重新打开文件它可以工作,但我想这是一个丑陋的解决方案。

有什么方法/成员函数可以回到起点吗?

【问题讨论】:

  • cin 接受控制台输入,它不从文件中读取!使用std::getline 看看是否可行。
  • 对不起,我打错了。它将是文件 >> 行。
  • 你对这些信息做了什么(计算的行号)?
  • seekg() 有效,谢谢,但为什么您建议另外调用 clear()?
  • 以防 eof 由第一遍设置。

标签: c++ string file-io ifstream stdstring


【解决方案1】:

“我这样计算文件的行数……之后我想逐行读取”

你可以同时做这两件事:

std::ifstream filestream("somefile.ext");
std::vector<std::string> lines;

std::string line;
while (std::getline(filestream, line)) {
    lines.push_back(line);
}
std::cout << "file has " << lines.size() << " lines" << std::endl;

还要注意:

while (!file.eof()) {
    std::string row;
    file >> row;
    ... // doing something with row
}

不安全,因为&gt;&gt; 可能会到达文件末尾,或者可能会发生一些错误,因此循环体的其余部分不应依赖于它被正确读取。这是一个好方法:

std::string word;
while (file >> word) {
    ... // doing something with row
}

实际上是逐字阅读(不是逐行)。

【讨论】:

  • 大文件吃内存
  • '不安全,因为 >> 可能会到达文件末尾或可能发生一些错误,因此循环体的其余部分不应依赖于它被正确读取。 - 实际上提取一些字符并点击 eof 很好,没有 eof 会出现失败状态,不是。但是,'这是一个好方法:没问题。
【解决方案2】:

清除错误位的 istream 并返回文件的开头。这是否是您想要做的最佳方法是另一个问题,具体取决于您的实际目标。

int main(int argc, char *argv[])
{
    ifstream file("file.txt");

    int n = count(istreambuf_iterator<char>(file), istreambuf_iterator<char>(), '\n') + 1;

    file.clear();
    file.seekg(0);

    string row;    

    while (file >> row)
        cout << row << endl;

    return (0);
}

【讨论】:

    【解决方案3】:

    如果您使用ifstream 遍历文件,您可以使用seekg 调整读取位置

    例如:

    std::ifstream file(...);
    int linecount = 0;
    while (!file.eof()) {
        if (file.get() == '\n') { ++linecount; }
    }
    // Clear the eofbit.  Not necessary in C++11.
    file.setstate(0);  
    // Rewind to the beginning of the file.
    file.seekg(0);
    

    如果您使用的是cin,那不是文件。所以你不能倒带。您可以存储每一行​​(如@LihO 建议的那样),或者重新处理您的处理,以便您遍历您的输入一次,同时计算行数。

    【讨论】:

      猜你喜欢
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      • 2022-09-22
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多