简体   繁体   English

为什么vector.size()在一行中读得太少?

[英]why does vector.size() read in one line too little?

when running the following code, the amount of lines will read on less then there actually is (if the input file is main itself, or otherwise) why is this and how can i change that fact (besides for just adding 1)? 当运行以下代码时,行数的读取将少于实际的行数(如果输入文件本身是main本身,否则),这是为什么呢,我又该如何更改这一事实(仅加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;
}

The code you have is sound. 您拥有的代码是正确的。 Here's a small test case that might help: 这是一个可能有用的小测试用例:

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;
}

Output: 输出:

read: abc
read: 
size: 2
---
read: abc
read: 123
size: 2
---
read: abc
read: 123
size: 2

I think I have tracked down the source of your problem. 我想我已经找到了问题的根源。 In Code::Blocks, a completely empty file will report that there is 1 line in it (the current one) in the gizmo on the status bar at the bottom of the IDE. 在Code :: Blocks中,一个完全空的文件将报告IDE底部状态栏中的小控件中有1行(当前行)。 This means that were you actually to enter a line of text, it would be line 1. In other words, Code::Blocks will normally over-report the number of actual lines in a file. 这意味着如果您实际上要输入一行文本,那就是第1行。换句话说,Code :: Blocks通常会过度报告文件中的实际行数。 You should never depend on CB, or any other IDE, to find out info on files - that's not what they are for. 您绝对不应依赖CB或任何其他IDE来查找文件信息-这不是它们的用途。

Well, if the last line of your file is just '\\n', you don't push it into the vector. 好吧,如果文件的最后一行只是'\\ n',则不要将其压入向量中。 If you want it to be there, change the loop to: 如果您希望它存在,请将循环更改为:

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";
}

Use the gcount() member to check how many characters were read in the last read - this will return 1 if it only read a delimiter character. 使用gcount()成员检查最后一次读取的字符数-如果它仅读取定界符,则将返回1。

Ok so here is an explanation that you will hopefully understand. 好的,这是一个希望您能理解的解释。 Your code should work fine if the file we're talking about doesn't end with newline. 如果我们正在讨论的文件不以换行符结尾,则您的代码应该可以正常工作。 But what if it does? 但是,如果可以呢? Let's say it looks like this: 假设它看起来像这样:

"line 1"
"line 2"
""

Or as a sequence of characters: 或作为字符序列:

line 1\nline 2\n

This file has THREE lines -- the last one being empty but it's there. 该文件有三行-最后一行是空的,但是它在那里。 After calling getline twice, you've read all the characters from the file. 两次调用getline之后,您已经从文件中读取了所有字符。 The third call to getline will say oops, end of file, sorry no more characters so you'll see only two lines of text. 对getline的第三次调用将显示oops,文件结尾,对不起没有更多字符,因此您只会看到两行文本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM