Инициализация массива объектов с данными из текстового файла - PullRequest
1 голос
/ 10 ноября 2009

Я получаю системную ошибку при попытке скомпилировать приведенный ниже код в Visual C ++ 2008 Express. Я пытаюсь инициализировать массив объектов с данными, считанными из файла. Я думаю, что внутри цикла while что-то не так, потому что, когда я инициализирую эти объекты вручную без цикла while, кажется, что он работает. Вот код и текстовый файл:

#include <iostream>
#include <string>
#include "Book.h"

using namespace std;            

int main()
{
    const int arraySize = 3;
    int indexOfArray = 0;

    Book bookList[arraySize];
    double tempPrice;//temporary stores price
    string tempStr;//temporary stores author, title


    fstream fileIn( "books.txt" );

    while ( !fileIn.eof( ))
    {
        getline(fileIn,tempStr);
        bookList[indexOfArray].setAuthor(tempStr);

        getline(fileIn,tempStr);
        bookList[indexOfArray].setTitle(tempStr);

        fileIn >> tempPrice;
        bookList[indexOfArray].setPrice(tempPrice);

        if ( indexOfArray < arraySize ) //shifting array index while not exceeding array size
            indexOfArray++;
    }

    fileIn.close();

    return 0;
}

и текстовый файл:

Author1
Book1
23.99
Author2
Book2
10.99
Autho3
Book3
14.56

Ответы [ 3 ]

5 голосов
/ 10 ноября 2009

Похоже, вы пытаетесь записать в bookList [3] в цикле. Вы будете трижды проходить циклы, заполняя каждый раз приращением indexOfArray массива Это оставит indexOfArray равным 3 - ваше условие в том виде, в каком оно написано, позволит увеличить indexOfAray до 3. Затем, если у вас в файле данных будет новая строка после «14.56», вы будете повторять цикл еще раз и пытаться передать пустой строка в bookList [indexOfArray] .setAuthor (), ведущая к segfault, так как indexOfArray находится за концом массива.

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

2 голосов
/ 10 ноября 2009

В вашем коде есть еще одна ошибка во время выполнения: вы не читаете всю строку с вызовом fileIn >> tempPrice;. Следующий вызов getline() будет читать до конца строки, поэтому вы получите пустую строку, когда ожидаете автора.

Затем вы отключаетесь на одну строку в текстовом файле и пытаетесь преобразовать заголовок в двойной. Это делает сигнал fstream ошибкой, и после этого у вас проблемы.

Бретт прав, вектор с push_back - лучшее решение здесь.

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

if(fileIn >> tempPrice)
{
    bookList[indexOfArray].setPrice(tempPrice);
}
else
{
    break;
}

if(!getline(fileIn,tempStr))
{
    break;
}
0 голосов
/ 10 ноября 2009

Ключ должен быть в содержании

#include "Book.h"

Я скопировал ваш код и заменил #include своим предположением о том, как может выглядеть класс Book:

class Book
{
    std::string auth;
    std::string title;
    double price;
public:
    void setAuthor(std::string& str)
    {
        auth = str;
    }

    void setTitle(std::string& t) 
    {
        title = t;
    }

    void setPrice(double d)
    {
        d = price;
    }
};

и оно скомпилировано. Возможно, вы могли бы поделиться своим Book.h, или искать там какие-либо проблемы? Начните с простого определения из Book (как выше) и начинайте читать код, пока не найдете строки, которые вызывают проблему. Это грубый метод выяснения проблемы, но иногда это самый прямой способ.

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