динамическое распределение памяти для структуры при чтении из файла в C ++

У меня есть структура

typedef struct student
{
    char name[10];
    int age;
    vector grades;
} student_t;

И я'Я записываю его содержимое в двоичный файл.

Я пишу в разное время и имею много данных в файле, которые написаны из этой структуры.

Теперь я хочу прочитать ВСЕ данные, которые есть в двоичном файле, в структуре. Я'Я не уверен, как я могу выделить память (динамически) для структуры, чтобы структура могла вместить все данные в структуре.

Можете ли вы помочь мне с этим.

Код:

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;


typedef struct student
{
    char name[10];
    int age;
    vector grades;
}student_t;

int main()
{
    student_t apprentice[3];
    strcpy(apprentice[0].name, "john");
    apprentice[0].age = 21;
    apprentice[0].grades.push_back(1);
    apprentice[0].grades.push_back(3);
    apprentice[0].grades.push_back(5);

    strcpy(apprentice[1].name, "jerry");
    apprentice[1].age = 22;
    apprentice[1].grades.push_back(2);
    apprentice[1].grades.push_back(4);
    apprentice[1].grades.push_back(6);

    strcpy(apprentice[2].name, "jimmy");
    apprentice[2].age = 23;
    apprentice[2].grades.push_back(8);
    apprentice[2].grades.push_back(9);
    apprentice[2].grades.push_back(10);

    // Serializing struct to student.data
    ofstream output_file("students.data", ios::binary);
    output_file.write((char*)&apprentice, sizeof(apprentice));
    output_file.close();

    // Reading from it
    ifstream input_file("students.data", ios::binary);
    student_t master;

    input_file.seekg (0, ios::end);
    cout < input_file.tellg();

    std::vector> std::noskipws;
    std::copy(istream_iterator(input_file), istream_iterator(), std::back_inserter(s));*/

    while(input_file >> master) // throws error
    {
        s.push_back(master);
    }
    return 0;
}
 alestanis20 окт. 2012 г., 00:54
зЬгср? ай мои глаза!
 Arun S20 окт. 2012 г., 00:12
скажем, я записываю массив struct скажем student_t [5] в двоичный файл и делаю это 4 раза. Я хочу получить данные из двоичного файла на структуру. Но я не буду знать, сколько таких структур было написано (так как пользователь может написать любое количество таких структурных массивов). Я хотел бы знать, как вывести динамические данные на структуру.
 GManNickG20 окт. 2012 г., 00:14
Вы должны записать, сколько структур было написано.
 Arun S20 окт. 2012 г., 00:59
@alestanis - я просто работал над динамически читаемой частью. Итак, Динт уделяет много внимания остальному. И это пример кода, который я пытаюсь, который я взял его из сети.
 alestanis20 окт. 2012 г., 00:08
Я нене понимаю вашего вопроса.vector уже обрабатывает динамическое распределение. Вы имеете в виду, что у вас есть контейнер, полныйstudent_t что вы хотите динамически выделить?
 alestanis20 окт. 2012 г., 00:18
Если ваша проблема связана с двоичным файлом, вы можете проверить его на EOF (= End Of File). Если речь идет о части кода C ++, вы должны использоватьvector, Векторы уже обрабатывают динамическое распределение, и вы можете вызвать.size() на них.
 dmckee20 окт. 2012 г., 00:16
Зачем использовать вектор в одном месте, но (1) не использовать вектор для получения нескольких студентов и (2) использовать строку в стиле c вместоstd::string? Я имею в виду, что я игнорирую расширенные функции, чтобы узнать о низкоуровневых вещах, но половина их использования кажется глупой.

Ответы на вопрос(3)

Самый простой подход - распаковать вектор так, чтобы вы записывали в файл не вектор, а массив целых чисел вместе с числом целых в массиве.

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

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

 Arun S20 окт. 2012 г., 00:18
На самом деле у меня нет проблем с переносом данных в вектор. Если бы я знал, что хочу получить 3 набора структурных данных, я могу выделить его как student_t s [3]. Но здесь я не могу, если это будет 3 (это может быть любое произвольное значение, основанное на содержимом файла). Я'Я не уверен, как это сделать. Можете ли вы помочь мне с этим.
 Richard Chambers20 окт. 2012 г., 00:32
@ user1420351, вам нужно будет использовать один из классов коллекции, таких как vector, для динамического добавления копий структур, считанных из файла. Или вы можете сделать то, что предлагает Джефф с новым, но для этого вам нужно знать, сколько их в файле, так что, вероятно, коллекция, такая как vector, будет гораздо предпочтительнее.
 Geoff Montee20 окт. 2012 г., 00:22
Похоже, вы либо хотите динамические массивы, какstudent_t* s = new student_t[num_structs]; илиvector вашей структуры, как.std::vector s;

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

2 13  8 

Первое число (2) дает количество структур, хранящихся в файле. Затем следуют блоки данных. Каждый блок данных начинается с числа, которое определяет размерgrades вектор (13 для первой структуры, 8 для второй).

В этом случае вы читаете int в начале файла. Теперь вы знаете, что в файле сохранены 2 структуры. Затем вы читаете следующий int, 13 в этом случае. Это говорит о том, что вам нужен вектор с емкостью 13. Вы можете создать его, а затем прочитать все ваши значения. Вы будете знать, когда остановиться, поскольку знаете, сколько данных у вас есть в этой структуре: 10 символов (имя), 1 тип (возраст), 13 дюймов (классы). После того, как вы прочитали все это, вы знаете, что следующий int будет частью следующей структуры в файле. Это будет число 8, которое говорит вам, что следующей структуре нужен вектор емкости 8.

И т. Д., И т. Д., Пока вы не прочитаете все.

Обратите внимание, что этот метод ввода / вывода двоичных файлов не является переносимым. Для этого есть две причины. Во-первых, размер int может отличаться для разных платформ. Во-вторых, способ, которым int (и другие данные, превышающие один байт) хранятся в двоичной форме, также может отличаться, даже если они имеют одинаковый размер (см.http://en.wikipedia.org/wiki/Endianness для объяснения.) Но если вы неЕсли ваша программа и файлы, которые она генерирует, в любом случае будут переносимыми, то описанного выше метода будет достаточно.

Решение Вопроса

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

РЕДАКТИРОВАТЬ: Для чтения файла вы можете сделать что-то вроде этого:

ifstream myfile;
myfile.open(file_name);
if (myfile.is_open()) {
    while (myfile) {
        string s;
        getline(myfile, s);
        // Do something with the line
        // Push information into students vector
    }
}

Дон»Не забудьте добавить бинарные опционы тоже.

Дляname внутри вашегоstudent_t структура, было бы намного проще объявить его какstring, Таким образом, вы бы ненужно использоватьstrcpy и тому подобное, и вы могли бы просто напечататьmystudent.name = "jimmy"

 Arun S20 окт. 2012 г., 00:51
Я добавил код.
 alestanis20 окт. 2012 г., 01:07
Это сработало? У меня нетя много работал с бинарными файлами
 Arun S20 окт. 2012 г., 00:43
Я пытался сделать это в то время как (input_file >> master) {s.push_back (master); } но я получаю ошибку во время части. Можете ли вы помочь мне.
 Arun S20 окт. 2012 г., 01:06
Большое спасибо за ваше решение.
 Arun S20 окт. 2012 г., 01:12
сейчас пытаюсь. У меня все еще есть некоторые проблемы с этим.
 alestanis20 окт. 2012 г., 08:47
Хорошо! Дон»не забудьте принять ответ, если вы решили свою проблему с нашей помощью.
 alestanis20 окт. 2012 г., 00:46
Можете ли вы отредактировать свой вопрос, чтобы добавить код, который вы только что попробовали? Не глядя на код этоочень трудно помочь.
 Arun S20 окт. 2012 г., 02:01
Наконец-то все заработало. Цикл до EOF, чтение файла в структуру и добавление толкнул структуру в вектор.

Ваш ответ на вопрос