Как сохранить указатель на структуру в C, чтобы данные не терялись? - PullRequest
0 голосов
/ 09 мая 2018

У меня есть этот код

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

typedef struct {
  char   brand[40];
  int    year;
  int    km;
  float  price;
}Autos;

int userInput;
void menu();
void scanCars(Autos *pointer);
void print_struct(Autos *pointer);


int main(int argc, char const *argv[])
{
  Autos *pointerCar, Cars;
  pointerCar=&Cars;
  pointerCar=(Autos  *)malloc(5*sizeof(Autos));
  int value= 1;
    while (value)
    {
    menu();
      switch (userInput)
      {
        case 1:
         scanCars(pointerCar);

          break;
        case 2:
          print_struct(pointerCar);

          break;
        case 3:
          value=0;
          break;
      }

    }
  free(pointerCar);
  return 0;
}
void menu()
{
    printf("1) Input Cars:\n" );
    printf("2) Print Cars:\n" );
    printf("3) Exit\n" );
    scanf("%d", &userInput );
    printf("=================\n" );
}
void scanCars(Autos *pointer)
{
  printf("1) Scanning CARS:\n");
  for (int i = 0; i < 2; i++)
  {
    printf("Brand:");
    scanf("%s", (pointer+i)->brand);

    printf("Year: ");
    scanf("%d", &(pointer+i)->year );

    printf("Kilometros:");
    scanf("%d",&(pointer+i)->km );

    printf("price: ");
    scanf("%f",&(pointer+i)->price );
  }
    printf("=================\n" );

}
void print_struct(Autos *pointer)
{
  for (int i = 0; i < 3; i++)
  {
    printf("Car #[%d]\n",i+1 );
    printf("Brand: %s\n",(pointer+i)->brand);
    printf("Year: %d\n",(pointer+i)->year );
    printf("Kilometraje: %d\n",(pointer+i)->km );
    printf("Price: $%.2f\n",(pointer+i)->price );
    printf("=================\n" );
  }

}

Код отлично работает для хранения данных о некоторых автомобилях, а затем распечатывает их при запросе.

Проблема:

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

Пример:

  1. каждый *pointerCar имеет 5 автомобилей
  2. Так как сохранить *pointerCar to array[3] of pointerCars
  3. В общей сложности у меня будет 15 автомобилей, но на каждом АВТОС будет 5 машин

Моя проблема в том, что каждый раз, когда я запускаю код, данные, которые я писал с последних машин, переписываются. Image for Input Cars Image for Printing Cars
enter image description here

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

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

Autos *pointerCar, Cars; - не делайте этого, это ухудшает читабельность. Я предполагаю, что вы хотели объявить два указателя: pointerCar - для одного автомобиля и cars для множества автомобилей. В вашем коде вы объявляете указатель pointerCar и переменную Cars.

Установите одно соглашение об именах и придерживайтесь его. Если вы используете CamelCase для типов, не используйте его для переменных (вместо этого используйте camelCase или snake_case). Не используйте множественное число для типов. Я бы написал так:

Auto *single_car;
Auto *cars;

Используйте calloc для инициализации структуры и массива, поскольку он заполняет выделенную память нулями, что удобно.

cars = (Auto*) calloc(5, sizeof(Auto));

А теперь выпуск

Вы теряете свой последний ввод, потому что каждый раз, когда вы вызываете функцию scanCars, вы передаете один и тот же указатель снова и снова. Ваш *pointerCar указывает на массив из 5 Auto, затем вы заполняете его данными в scanCars и возвращаетесь из функции. В следующий раз, когда вызывается scanCars, ему передается тот же указатель в качестве аргумента, и данные перезаписываются.

В общей сложности у меня будет 15 автомобилей, но на каждом АВТОС будет 5 машин;

Что-то здесь не так. У вас есть только один определенный тип: Autos (который должен быть просто Auto). Если вы выделите место для 5 Autos, вы получите указатель на память, подготовленную для хранения 5 структур Auto, и ничего более.

Если вы хотите сгруппировать ваши Autos в какой-то гипотетический гараж, вы должны создать таблицу указателей на Auto (или просто сказать: таблица таблиц Auto). Например:

Auto *garage[3];
garage[0] = (Auto*) calloc(5, sizeof(Auto));
garage[1] = (Auto*) calloc(5, sizeof(Auto));
garage[2] = (Auto*) calloc(5, sizeof(Auto));

И теперь каждый элемент garage содержит массив из 5 Autos. Чтобы получить доступ к машине в гараже, вы напишите: garage[1][0].year.

Теперь вы можете передать вам гараж scanCars Функция: scanCars(garage[0]). Не забудьте настроить цикл for в scanCars, потому что он настроен на заполнение только 2 автомобилей и теперь должен иметь 5.

0 голосов
/ 09 мая 2018

Эту проблему легко решить, используя массив указателей.

Autos *pointerCar;

Этот указатель может использоваться для хранения адреса одной структуры типа Autos. Вы можете взять массив следующим образом.

Autos *pointerCar[number_of_cars];

Для i-го автомобиля выделите i-й указатель через malloc как

pointerCar[i]=(Autos  *)malloc(sizeof(Autos));

Если у вас нет знаний о массиве указателей, обратитесь к this .

0 голосов
/ 09 мая 2018

Если у вас есть 5 автомобилей, объявите массив автомобилей: Auto Cars[5]; Затем вы указываете pointerCar на каждую из машин от 0 до 4 в последовательности.

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