1

运行以下代码时,读取的行数将少于实际的行数(如果输入文件本身是主文件,或者其他)为什么会这样,我该如何改变这个事实(除了只加 1)?

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

using namespace std;

int main()
{
    // open text file for input
    string file_name;

    cout << "please enter file name: ";
    cin  >> file_name;

    // associate the input file stream with a text file
    ifstream infile(file_name.c_str());

    // error checking for a valid filename
    if ( !infile ) {
        cerr << "Unable to open file "
             << file_name << " -- quitting!\n";
        return( -1 );
        }
        else cout << "\n";

    // some data structures to perform the function
    vector<string> lines_of_text;
    string textline;

    // read in text file, line by line
    while (getline( infile, textline, '\n' ))   {
        // add the new element to the vector
        lines_of_text.push_back( textline );

        // print the 'back' vector element - see the STL documentation
        cout << "line read: " << lines_of_text.back() << "\n";
    }
cout<<lines_of_text.size();
    return 0;
}
4

4 回答 4

2

您拥有的代码是合理的。这是一个可能有帮助的小测试用例:

void read_lines(std::istream& input) {
  using namespace std;
  vector<string> lines;
  for (string line; getline(input, line);) {
    lines.push_back(line);
    cout << "read: " << lines.back() << '\n';
  }
  cout << "size: " << lines.size() << '\n';
}

int main() {
  {
    std::istringstream ss ("abc\n\n");
    read_lines(ss);
  }
  std::cout << "---\n";
  {
    std::istringstream ss ("abc\n123\n");
    read_lines(ss);
  }
  std::cout << "---\n";
  {
    std::istringstream ss ("abc\n123");  // last line missing newline
    read_lines(ss);
  }
  return 0;
}

输出:

read: abc
read: 
size: 2
---
read: abc
read: 123
size: 2
---
read: abc
read: 123
size: 2
于 2010-04-22T22:08:10.597 回答
2

我想我已经找到了你问题的根源。在 Code::Blocks 中,一个完全空的文件会在 IDE 底部的状态栏上的 gizmo 中报告其中有 1 行(当前行)。这意味着如果您实际输入一行文本,它将是第 1 行。换句话说,Code::Blocks 通常会过度报告文件中的实际行数。您永远不应该依赖 CB 或任何其他 IDE 来查找有关文件的信息 - 这不是它们的用途。

于 2010-04-22T22:11:16.913 回答
0

好吧,如果文件的最后一行只是“\n”,则不要将其推入向量中。如果您希望它在那里,请将循环更改为:

while (getline( infile, textline, '\n' ).gcount() > 0) 
{
    if (infile.fail()) break; //An error occurred, break or do something else

    // add the new element to the vector
    lines_of_text.push_back( textline );

    // print the 'back' vector element - see the STL documentation
    cout << "line read: " << lines_of_text.back() << "\n";
}

使用该gcount()成员检查在上次读取中读取了多少个字符 - 如果它只读取分隔符,这将返回 1。

于 2010-04-22T21:31:07.620 回答
-1

好的,这里有一个解释,希望您能理解。如果我们正在讨论的文件不以换行符结尾,您的代码应该可以正常工作。但如果真的发生了怎么办?假设它看起来像这样:

"line 1"
"line 2"
""

或者作为一个字符序列:

line 1\nline 2\n

这个文件有三行——最后一行是空的,但它就在那里。两次调用 getline 后,您已经从文件中读取了所有字符。第三次调用 getline 会说 oops, end of file, sorry no more characters 所以你只会看到两行文本。

于 2010-04-22T22:04:40.693 回答