c - 如何在 C 中存储结构指针,以免数据丢失?
问题描述
我有这个代码
#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" );
}
}
该代码运行良好,可以存储一些汽车数据,然后在需要时打印出来。
问题:
当我第二次尝试存储新车数据时,我丢失了最后一次输入。所以我的问题是如何存储一个新的结构数组并打印整个数据:
例子:
- 每个
*pointerCar
有 5 辆汽车 - 那么如何保存
*pointerCar to array[3] of pointerCars
- 我总共将拥有 15 辆汽车,但每辆汽车将拥有 5 辆汽车
解决方案
首先,为了使代码更具可读性和更易于调试,需要避免一些事情:
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 个 Auto 分配空间,您将获得一个指向内存的指针,该内存已准备好存储 5 个 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 辆。
推荐阅读
- javascript - CSS 添加第二个过渡
- javascript - 我创建了用于自动显示当前月份的 java,但我试图始终显示下个月。例如:如果六月 - 显示“七月”
- sql - 使用 codeigniter 将连接表中的列连接到另一列
- r - 如何pivot_longer 变量名称中包含整数和变量的数据框?
- reactjs - 我无法更改 setArray 的状态。我可以改变其他使用状态的状态,但不能改变这个
- javascript - 个人资料图片和生物输入更新
- android - 在 Hilt 中使用 ActivityRetainedScoped 时,存储库何时会被销毁?
- terraform - 为什么 `terraform fmt` 似乎没有改变任何文件名时会输出文件名?
- python - 如何在“for循环”中插入不同的列表切片?
- metrics - OpenTSDB 默认指标