читать из файла в массив структур внутри структур в C ++ - PullRequest
2 голосов
/ 05 августа 2009

Я задавал этот вопрос ранее здесь , и аналогичный вопрос был закрыт.

ТАК, основываясь на комментарии другого пользователя, я перефразировал свой вопрос:

В первом посте я пытался прочитать данные из файла в массив со структурой. Используя indata << p [i] и >> p.fId, я смог прочитать значения из данных. файл в PersonId.

Теперь я хочу попробовать это:

struct PersonId
{
    int fId;
}; 

struct PersonData
{
    public:
        typedef PersonData* Ptr;
        PersonData();
        PersonId fId;
        istream& read(std::istream&);
};

istream& PersonData::read(std::istream& is) 
{
    is >> fId;
    return is;
}

istream& operator >> (istream& is, PersonData &p)
{
    // is >> p.fId;
    return p.read(is);
}

int main ()
{
    ifstream indata; // indata is like cin
    int i;
    indata.open("persons.txt", ios::in); // opens the file

    if(!indata) 
    { // file couldn't be opened
          cout << "Error: file could not be opened" << endl;
          exit(1);
    }

    int n = 5;

    PersonData* p;
    p = (PersonData*) malloc (n * sizeof(PersonData));


    while ( !indata.eof() )
    { 
        indata >> p[i];
        i++;
    }

    for(i = 0; i < n; ++i)
    {
        cout << "PersonData [" << i << "] is " << p[i] << endl;
    }
    return 0;
}

Я хочу использовать функцию-член «чтение» для фактического чтения значений в структуры, определенные PersonData. Мой вопрос:

  1. Как прочитать данные из файла в структуру PersonId, которая хранится в структуре PersonData ??

  2. При чтении PersonData [i] я должен видеть, что у него есть структура PersonId с обновленным значением.

Надеюсь, мои вопросы теперь понятны?

Ответы [ 2 ]

2 голосов
/ 05 августа 2009

У вас есть:

istream& operator >> (istream& is, PersonId &p)
{
    is >> p.fId;
    return is;
}

отсутствует, после struct PersonId;

Это необходимо для корректной работы is >> fId внутри read ().

Также исправьте cout, чтобы использовать p [i] .fId.fId.

Отлично работает!

На стилистической ноте, теперь вы в C ++, не используйте malloc, используйте new, а еще лучше, используйте std :: vector <>, который позаботится о подборе размеров для вас.

1 голос
/ 06 августа 2009

ОК, сначала немного ворча :-) Вы говорите, что хотите. Вы написали, как вы пытаетесь. Отлично. Я думаю, что результат не тот, что вы ожидали. Но вы не сказали нам, какой результат вы получаете и почему вы разочарованы этим. Когда я смотрю на ваш код, он не должен компилироваться. Проблема здесь:

istream& PersonData::read(std::istream& is) 
{
    is >> fId;
    return is;
}

Я не вижу ни одного оператора >>, определенного для типа PersonId, а fId имеет тип PersonId. Я прав? Или, может быть, где-то определен оператор >>, и вы не просто вставили его в свой вопрос? Мой хрустальный шар неясен. Если я правильно угадал, решение дает Дэйв Гэмбл:

istream& operator >> (istream& is, PersonId &p)
{
    is >> p.fId;
    return is;
}

Вы написали "все еще получаете ошибки при попытке доступа к PersonData". Кажется, на этот раз хрустальный шар Дейва тоже неясен, он не может сказать, какие у вас проблемы. Я тоже не могу. Вы должны либо предоставить нам детали, либо отправить нам лучшие хрустальные шары. Может быть, вы пропустили его другой совет: «Также исправьте cout, чтобы использовать p [i] .fId.fId.» Это значит, что вместо написания

cout << "PersonData [" << i << "] is " << p[i] << endl;

вы должны написать

cout << "PersonData [" << i << "] is " << p[i].fId.fId << endl;

Может быть и другая проблема - вы не имеете в виду соответственно членов пространства имен std - иногда вы пишете istream, а иногда пишете std :: istream, вместо std :: endl пишете endl. Возможно, поиск Кенига сработает для вас, я не очень хорош, но добавление префикса std :: может помочь (конечно, если это ваша проблема).

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