почему vector.size () слишком мало читает в одной строке? - PullRequest
1 голос
/ 23 апреля 2010

при запуске следующего кода количество строк будет считываться меньше, чем есть на самом деле (если входной файл сам по себе 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;
}

Ответы [ 4 ]

2 голосов
/ 23 апреля 2010

Я думаю, что выследил источник вашей проблемы.В Code :: Blocks полностью пустой файл сообщит, что в нем находится 1 строка (текущая) в гизмо в строке состояния в нижней части IDE.Это означает, что если бы вы на самом деле вводили строку текста, это была бы строка 1. Другими словами, Code :: Blocks обычно переоценивает количество фактических строк в файле.Вы никогда не должны зависеть от CB или любой другой IDE, чтобы узнать информацию о файлах - это не то, для чего они.

2 голосов
/ 23 апреля 2010

Код у вас есть звук.Вот небольшой тестовый пример, который может помочь:

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
0 голосов
/ 23 апреля 2010

Хорошо, вот объяснение, которое вы, надеюсь, поймете.Ваш код должен работать нормально, если файл, о котором мы говорим, не заканчивается переводом строки.Но что, если это произойдет?Скажем, это выглядит так:

"line 1"
"line 2"
""

Или как последовательность символов:

line 1\nline 2\n

Этот файл содержит ТРИ строки - последняя пустая, но она есть.После двойного вызова getline вы прочитали все символы из файла.Третий вызов getline скажет "упс", конец файла, извините, больше нет символов, поэтому вы увидите только две строки текста.

0 голосов
/ 23 апреля 2010

Ну, если последняя строка вашего файла просто '\ 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, если будет прочитан только символ разделителя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...