Как перенести информацию из текстового файла в динамические векторы структур

#c #vector #dynamic #struct

#c #вектор #динамический #структура

Вопрос:

Я пытаюсь перенести информацию о драйвере из текстового файла в динамические векторы структур. У меня есть текстовый файл, такой:

 Paulo Andrade
2  23  12  1995  76  0.5  0 

Faisca
3   1   1  1980  50  9.5  1    

Diana Alves Pombo
4  1  10  1990  55  4.5  0 

Ana Luisa Freitas
7  12  7  1976  68  1.0  3
  

Первая строка — это имя водителя, вторая — его идентификатор, дата рождения, вес, опыт и наказание.

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

Ответ №1:

это динамически распределяемый массив, использующий malloc, а затем перераспределяющий для изменения (увеличения) его размера

например :

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct Driver {
  char * name;
  int ID;
  int day;
  int month;
  int year;
  int weight;
  float experience;
  int punishment;
} Driver;

int main(int argc, char ** argv)
{
  if (argc != 2) {
    printf("Usage : %s <file>n", *argv);
    return -1;
  }
  
  FILE * fp = fopen(argv[1], "r");
  
  if (fp == NULL) {
    fprintf(stderr, "cannot open '%s'n", argv[1]);
    return -1;
  }
  
  char line[128];
  Driver * drivers = malloc(0); /* initial allocation, here empty */
  int n = 0;
  
  while (fgets(line, sizeof(line), fp) != NULL) {
    /* remove n */
    char * p = strchr(line, 'n');
    
    if (p != NULL)
      *p = 0;
    
    drivers = realloc(drivers, (n   1) * sizeof(Driver)); /* resize to add one element */
    
    Driver * d = amp;drivers[n  ];
    
    d->name = strdup(line);
    if ((fgets(line, sizeof(line), fp) == NULL) ||
        (sscanf(line, "%d %d %d %d %d %f %d",
                amp;d->ID, amp;d->day, amp;d->month, amp;d->year,
                amp;d->weight, amp;d->experience, amp;d->punishment)
        != 7)) {
      fprintf(stderr, "invalid file driver #%dn", n);
      fclose(fp);
      return -1;
    }
  }
  fclose(fp);
  
  /* check */
  Driver * sup = drivers   n;
  
  for (Driver * d = drivers; d != sup;   d)
    printf("%s : ID=%d birthdate=%d/%d/%d weight=%d experience=%f punishment=%dn",
           d->name, d->ID,
           d->day, d->month, d->year,
           d->weight, d->experience, d->punishment);

  return 0;
}
  

Компиляция и выполнение :

 pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall d.c
pi@raspberrypi:/tmp $ cat f
Paulo Andrade
2  23  12  1995  76  0.5  0 
Faisca
3   1   1  1980  50  9.5  1    
Diana Alves Pombo
4  1  10  1990  55  4.5  0 
Ana Luisa Freitas
7  12  7  1976  68  1.0  3
pi@raspberrypi:/tmp $ ./a.out f
Paulo Andrade : ID=2 birthdate=23/12/1995 weight=76 experience=0.500000 punishment=0
Faisca : ID=3 birthdate=1/1/1980 weight=50 experience=9.500000 punishment=1
Diana Alves Pombo : ID=4 birthdate=1/10/1990 weight=55 experience=4.500000 punishment=0
Ana Luisa Freitas : ID=7 birthdate=12/7/1976 weight=68 experience=1.000000 punishment=3
pi@raspberrypi:/tmp $ 
  

Начальное malloc(0) может показаться странным, но оно необходимо для того, чтобы после использования перераспределить или, если вы предпочитаете, сделать Driver * drivers = NULL; . Каждый раз я выделяю только еще одну запись, также возможно сначала malloc более 0, а затем перераспределять более чем на один элемент, когда это необходимо для лучшей производительности в случае, если в конечном массиве много элементов.

Предупреждение drivers = realloc(drivers, ...) может или нет перемещать выделенный массив, чтобы иметь возможность найти больше места, но вам всегда нужно предполагать изменение его адреса, вот почему я переназначаю результат в драйверах

Комментарии:

1. Можете ли вы привести мне пример? Это проще для понимания. Моя проблема заключается в синтаксисе, в том, как я должен писать код, чтобы использовать динамические векторы в структурах