Как перенести информацию из текстового файла в динамические векторы структур - PullRequest
0 голосов
/ 23 апреля 2019

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

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 Ответ

1 голос
/ 23 апреля 2019

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

, например:

#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 = &drivers[n++];

    d->name = strdup(line);
    if ((fgets(line, sizeof(line), fp) == NULL) ||
        (sscanf(line, "%d %d %d %d %d %f %d",
                &d->ID, &d->day, &d->month, &d->year,
                &d->weight, &d->experience, &d->punishment)
        != 7)) {
      fprintf(stderr, "invalid file driver #%d\n", 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=%d\n",
           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) может показаться странным, но это необходимо после использования realloc .Я выделяю только одну дополнительную запись каждый раз, также возможно malloc больше, чем 0 первоначально, тогда realloc для более чем еще одного элемента, когда это необходимо для лучшей производительности в случае, если есть многоэлементов в окончательном массиве.

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

...