Не выходит из цикла при чтении из файла

381
28 декабря 2016, 04:32

Во время считывания из файла функция не выходит из цикла,

Структура:

struct Example
{
    string Name;
    string Adder;
    int newList;
    int newListAdd;
};

Функция для чтения:

Example *readFile(ifstream &arg) {
    arg.open("other.txt", ios_base::in);
    Example *arg2 = new Example[2];
    int i = 0;
    if (arg.is_open()) {
        while (!arg.eof()) {
            getline(arg, (arg2[i]).Name);
            getline(arg, (arg2[i]).Adder);
            arg  >> (arg2[i]).newList >> (arg2[i]).newListAdd;
            i++;
        }
    } else {
        cout << "Error";
    }
    arg.close();
    return arg2;
}

Как пример файла:

gigehi
ihuiguh iuhi
222
111
girehgirh 
hjrto jojhortj
333
222
Answer 1

Данный цикл

    while (!arg.eof()) {
        getline(arg, (arg2[i]).Name);
        getline(arg, (arg2[i]).Adder);
        arg  >> (arg2[i]).newList >> (arg2[i]).newListAdd;
        i++;
    }

логически не верный.

Вы должны проверять, что цикл не будет продолжаться более двух раз, так как вы определили массив только из двух элементов, который вы собираетесь заполнить данными из файла

Example *arg2 = new Example[2];
                           ^^^^

Кроме того имеет место попытка чтения пустого файла, так как после того, как будет прочитана последняя запись файла, состояние конца файла еще не наступит, пока не будет предпринята попытка прочитать несуществующую запись после последней записи файла. А это значит, что в поля массива будут занесен неверные данные.

Что касается зацикливания, то после данного предложения с оператором operator >>

arg  >> (arg2[i]).newList >> (arg2[i]).newListAdd;

в буфере ввода сохраняется символ новой строки '\n', а функция std::getline Считывает строку до этого символа. В результате после первой итерации цикла в данном предложении

getline(arg, (arg2[i]).Name);

считывается пустая строка из-за оставшегося в буфере ввода символа новой строки от предыдущей итерации цикла. Следующее предложение

getline(arg, (arg2[i]).Adder);

считывает запись файла girehgirh , а затем предложение

arg  >> (arg2[i]).newList >> (arg2[i]).newListAdd;

пытается занести запись файла hjrto jojhortj в целые числа. Возникает ошибка ввода-вывод, которая так и сохраняется, а потому ничего далее из файла не считывается.

Вам надо либо все строки вводить с помощью функции std::getline, а затем строки преобразовывать в целые числа для целочисленных полей структуры. Либо после предложения

arg  >> (arg2[i]).newList >> (arg2[i]).newListAdd;

удалять оставшийся в буфере символ новой строки '\n'. Это можно сделать следующим образом

#include <limits>
//...
arg  >> (arg2[i]).newList >> (arg2[i]).newListAdd;
arg.ignore( std::numeric_limits<std::streamsize>::max()), '\n' );
READ ALSO
Удаление виджетов, размещенных в QLayout

Удаление виджетов, размещенных в QLayout

Есть QScrollArea или любой другой виджетВ него добавляются другие виджеты и, соответственно, рисуются на нем

390
В файл записываются левые данные c++

В файл записываются левые данные c++

При записи в файл, помимо текста добавляются различные символы, хотя если вызывать функцию без переменной с текстом, то все хорошо

353
Слоты и сигналы Qt

Слоты и сигналы Qt

Есть виджет, назовем его Link, и окно MainWindowНужно сделать так, чтобы по нажатию на виджет Link выполнялось какое-то действие из MainWindow, например...

447
Статическая переменная map. Использование как словарь [требует правки]

Статическая переменная map. Использование как словарь [требует правки]

Использую статические открытые переменные типа QMapЗаполнение произвожу с помощью статической функции, которая возвращает QMap

376