gpt4 book ai didi

c - 返回结构数组

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:43 25 4
gpt4 key购买 nike

我试图弄清楚如何修改我的代码以实际允许我在我的 readFile 中创建一个结构数组,然后将该数组返回给 main。

这是我的数据结构

struct data{

char *model;
float engineSize;
int cost;
char *color;
};

这是我的 readFile 函数的当前设置,然后是我当前用于此函数的调用。
 struct data * readFile(){

FILE *fp;
int c;
int count = 0;
char *line = NULL;
size_t len = 0;

fp = fopen("hw3.data", "r");

while ((c = fgetc(fp)) != EOF){

count++;

}

if (feof(fp)){

rewind(fp);

struct data *vehicles = malloc((sizeof(struct data))* count);


count = 0;
char *token = NULL;
while (getline(&line, &len, fp)!= -1){

printf("%s", line);

token = strtok(line, " ");
vehicles[count].model = token;

token = strtok(NULL, " ");
vehicles[count].engineSize = atof(token);

token = strtok(NULL, " ");
vehicles[count].cost = atoi(token);

token = strtok(NULL, " ");
vehicles[count].color = token;

}

}


}

这是我有我的菜单的主要地方,我将在这里调用我的 readFile 函数。
int main(){

int check = 1;
int input;

while (check == 1){

printf("Enter a value corresponding to a option on the menu below\n\n");

printf("1. Sort data by the float value & print high to low\n");
printf("2. Sort data by the float value & print low to high\n");
printf("3. Sort data by the int value & print high to low\n");
printf("4. Sort data by the int value & print low to high\n");
printf("5. Exit\n\n");

printf("Enter a value corresponding to the above menu\n");
scanf("%d", &input);

//readFile()

if(input == 1 || input == 2 || input == 3 || input == 4 || input == 5){

if (input == 5){

exit(0);

}if (input == 1){

//sort float high to low

}if (input == 2){

//sort float low to high

}if (input == 3){

//sort int value high to low

}if (input == 4){

//sort int value low to high

}

}else{

printf("Enter a correct value for the menus above\n\n" );
}

readFile();

}

}

谢谢

最佳答案

这几乎是正确的,这个想法还可以,但有几个问题:

while ((c = fgetc(fp)) != EOF){
count++;
}

这计算字节数,我认为根据您想要的后面的代码
行数。
while ((c = fgetc(fp)) != EOF){
if(c == '\n')
count++;
}

会给你行数。

在下面
token = strtok(line,  " ");
vehicles[count].model = token;
...
token = strtok(NULL, " ");
vehicles[count].color = token;

是有效的,但也许不是你想要的。 strtok成功返回 line + some_offset所以如果以后你需要
vehicles[i].mode 添加更多字符或 vehicles[i].color , 你可能
覆盖内存。 vehicles[i].color只是在偏移量 vehicles[i].model .如果你甚至想重新分配, realloc将失败,
因为您不会在请求的内存开始时重新分配
堵塞。同样通过这样做,您将丢失所请求内存的开头,
它会泄漏内存,因为您无法释放它( free(vehicles[i].color)
无效)1。

另一个问题是只有初始行会有正确的数量
分配的内存,如果你调用 getline与非 NULL指针和
非零长度, getline如有必要,将重新分配内存并更新
指针和长度。如果重新分配返回相同的地址,那么您的
以前的值将被覆盖。如果重新分配返回一个
不同的地址,你以前的指针将变得无效。

我建议(我认为这是唯一安全的方法)您使用 strdup 复制 token (如果可用,或 malloc + strcpy )
然后做:
while (getline(&line, &len, fp)!= -1){
// the strtok calls
...
free(line);
line = NULL;
len = 0;
}

这样,您的代码就不会泄漏内存,也不会覆盖内存。

编辑

I should instead be setting the values of model and color with strcpy instead



您可以使用 strcpy ,但您需要先分配内存,因为 modelcolor只是指针。 malloc只调用保留的内存,
它不会初始化它。所以只是做
strcpy(vehicles[count].model, token);

会错的,因为你会尝试在未定义的地方复制一些东西
地点。这就是我的意思

I'd suggest (and I think it is the only safe way here) that you do a copy of token with strdup (if available, or malloc+strcpy)


vehicles[count].model = malloc(strlen(token) + 1);
if(vehicles[count].model == NULL)
{
// error handling
// for example
// free everything and return

return NULL;
}

strcpy(vehicles[count].model, token);

函数 strdup基本上是这样做的: malloc + strcpy ,所以如果你的
系统有 strdup你可以这样做:
vehicles[count].model = strdup(token);
if(vehicles[count].model == NULL)
{
// error handling
// for example
// free everything and return

return NULL;
}

另一种选择是更改您的结构,而不是指向 char , 使用 char数组:
struct data{
char model[100];
float engineSize;
int cost;
char color[100];
};

现在您可以保存最大长度为 99 个字符的字符串(这应该足够了
型号名称和颜色),只需使用 strncpy相反,无需
额外的内存分配:
strncpy(vehicles[count].model, token, sizeof vehicles[count].model);
// making sure to terminate the string
vehicles[count].model[sizeof(vehicles[count].model) - 1] = 0;

Also I just haven't had a chance to change the code for free (line) line =null and len =0



我不知道你那是什么意思。只需在后面添加行
vehicles[count].color = token;

结束前 while环形。

So then also I should be using the get line like I was in the second iteration through the file because I am currently over allocating?



第二个循环很好,问题是你被分配了相同的(+
偏移量)到不同指针的内存位置以及何时 getline重新分配
并获得不同的地址,前一个指针变得无效。这就是为什么
free(line);
line = NULL;
len = 0;

很重要,您绝对应该这样做。

总结:您的循环很好,但您需要进行以下更改:
  • 复制token或更改结构以使用 char数组
  • 添加
    free(line);
    line = NULL;
    len = 0;

    循环结束时的行,你会没事的。


  • 注释

    1 vehicles[i].mode只会指向内存的开头
    当且仅当该行不以空格开头时才阻塞。就像你一样
    读取文件,您无法保证这是真的。即使它是
    真的,我不会指望这一点。最好在这里做安全的事情并做一个
    复制。 free(vehicles[i].color)肯定是错的。

    关于c - 返回结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48714250/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com