Структура для файла в C - PullRequest
0 голосов
/ 15 апреля 2020

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

typedef struct{
  char name[MAXSTRING]; //MAXSTRING is defined above
  int id;
}student;

И это student st, в котором я сохраняю имя и идентификатор.

У меня также есть файл, загруженный в это: student *stArray = load(argv[1]); //load() is a function in wich i open the file.

Теперь я хочу добавить содержимое st к stArray в этой функции:

int addStudent(student st, student *stArray); //It's supposed to insert an enty

, но я не знаю как. Кто-нибудь может помочь?

student *load(char *filename){

    FILE *fp = fopen(filename, "ab+");
    if (fp == NULL)
    {
        printf("File does not exist\n");
        abort();
    }

    student *students;

    fseek(fp, 0, SEEK_END);
    long fileSize = ftell(fp);
    if (fileSize == 0)
    {
        return NULL;
    }

    int numStudents = fileSize/sizeof(student);
    students = (student *)malloc(sizeof(student)*numStudents);
    if (students == NULL)
    {
        printf("Error allocating memory\n");
        abort();
    }

    return students;
}

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Я хочу добавить содержимое st в stArray

Чтобы добавить нового студента в уже созданный массив, просто увеличьте его размер, используя reallo c затем скопируйте нового студента в конце.

Но это невозможно, имея эту подпись

int addStudent(student st, student *stArray);

, потому что:

  1. вы не знаете размер текущего массива

  2. у вас нет возможности вернуть новый массив

Вам необходимо получить в аргументе размер массива или количество учеников, которые он запоминает

Чтобы вернуть новый массив, вы можете вернуть его адрес:

student * addStudent(student st, student *stArray, size_t size);

или использовать двойной указатель:

int addStudent(student st, student ** stArray, size_t size);

но кажется разумным также возвращать новый размер, иначе вызывающий должен обновить его, поэтому второе решение, вероятно, является лучшим, а возвращаемое значение может быть новым размером, иначе используйте также указатель для размер :

int addStudent(student st, student ** stArray, size_t * size);

и возвращаемое значение может использоваться для указания, если * 10 39 * reallo c было возможно или нет.

Примечание, которое я рассмотрел выше stArray - это не адрес, где st может быть безопасно скопировано, потому что имя содержит «add» и не является, например, «setStudent» или «saveStudent» et c, а также потому, что функция возвращает значение, значение которого должно иметь значение. Но если это так, просто сделайте memcpy (stArray, st, sizeof (st)); , и я действительно не знаю интереса возвращаемого значения, поэтому я не могу предложить, что возвращать.


Несколько замечаний по поводу вашего кода:

  • функция load вообще не загружает файл, он только выделяет блок памяти и возвращает его не инициализировано

  • режим «ab +» не позволяет читать содержимое файла, вам нужно будет использовать «rb» (кажется, вам нужен «b»)

  • , если файл не существует, ваш fopen создает его, сообщение, которое вы пишете, когда fopen завершается ошибкой, только если true, когда файл не существует и у вас нет права создавать его, но вы не указываете все другие возможные причины, не предполагайте, в чем проблема, используйте, например, perror .

  • Вы никогда не fclose файл, вам нужно сделать

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

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

0 голосов
/ 17 апреля 2020

Я попробовал другой подход, и это сработало. Спасибо всем за вашу помощь. Я не думаю, что этот вопрос кому-нибудь поможет. Не трать свое время.

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