Чтение файла: обработка строк по-разному - PullRequest
2 голосов
/ 05 апреля 2009

У меня много проблем при попытке прочитать файл на C ++. Основная проблема, с которой я сталкиваюсь, - это правильное чтение первой строки потока, поскольку она отличается от всех остальных строк.

Пример файла:

#Newbie 101|Exam 1|3
Person One|10
Person Two|20
Person Three|30

первая строка начинается с # и объявляет имя класса, имя assignmanet и общее количество студентов.

void Grading::loadData()
{
    string filename;
    cout << "Enter a filename with records to open: ";
    cin >> filename;

    std::ifstream file;
    file.open(filename.c_str(), std::ios::app);

    if (!file) {
        cout << "Unable to open the specified file" << endl;
        return;
    }

    string buffer;
    vector<Student> students;
    vector<Student>::iterator it;

    while (!getline(file, buffer, '|').eof()) {

        Student stud;
        string name;
        string tmpgrade;
        string course;
        string assignment;
        int totalstudents;

        // read first line
        if (buffer.find("#") == 0) {
            getline(file, course, '|');
            cout << "Course Name    : " << course << endl;
            cout << "Grading Item   : " << assignment << endl;
            cout << "Total Students : " << totalstudents << endl;
            cout << endl;
            continue;
        }


        getline(file, name, '|');
        getline(file, tmpgrade, '|');

        double grade = strtod(tmpgrade.c_str(), NULL);

        stud.name = name;
        stud.grade = grade;

        cout << "Name: " << stud.name << endl;
        cout << "Grade: " << stud.grade << endl;

        students.push_back(stud);

    }

Я очень ценю любые предложения о том, как исправить этот код, чтобы правильно прочитать файл. Большое спасибо заранее!

Ответы [ 3 ]

3 голосов
/ 05 апреля 2009

Похоже, что чтение / разбор первой строки должно находиться за пределами (над) вашего цикла. Тогда вам не придется беспокоиться о разборе двух разных типов строк в теле основного цикла.

0 голосов
/ 06 апреля 2009

С моей точки зрения, вы неправильно делаете то, что хотите.

LoadData() будет читать остановку токена каждый раз, когда читает '|' разделитель. При нахождении токена "# Newbie 101" он удаляется, поскольку начинается с символа #. Следующая итерация в своем цикле будет обрабатывать токен "Экзамен 1" (следующий ... в строке первая !!). Хорошо, хорошо. И затем на следующей итерации читается следующая, которая является "3 \ nPerson one" . Пожалуйста, обратите внимание на конец строки в середине строки! Учитывая вывод, я не уверен, что это то, что вы хотите, да?

AFAI понимаю, что вы хотите, чтобы ваша программа пропускала закомментированные строки (начиная с символа #). В качестве решения, вам лучше читать всю строку вместо getline(file_handle, line) в первом цикле. Не указывайте никаких «|» символ в качестве третьего параметра при вызове getline (), для получения строки whole должна быть взята '\ n'.

В этом первом цикле добавьте первую проверку, чтобы увидеть, начинается ли символ «#» в строке. Если это так, вызовите оператор continue. В противном случае введите второй вложенный цикл, чтобы интерпретировать все токены в вашей строке, на этот раз, используя find_first_of() метод строки, чтобы найти '|' персонаж. Повторяйте цикл, пока не прочитаете всю строку.

Вы могли бы либо подумать о BOOST tokeniser lib. Хотя я никогда не использовал его (или давным-давно, когда я был старшим), я помню, что это было вполне уместно для выполнения такой работы очень простым способом! Я верю, что есть хорошие библиотеки для чтения файлов и удаления комментариев. Может быть, в BOOST ... (это позор, мне действительно нужно глубже взглянуть на эту библиотеку ...)

0 голосов
/ 05 апреля 2009

Вам просто нужно обрабатывать первую строку отдельно как особый случай. Вы можете сделать это, читая в первой строке (конечно, проверяя, есть ли первая строка) вне основного цикла или обрабатывая внутри цикла для особого случая, используя логическое значение или счетчик строк.

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