替换自身值的结构数组 [英] Array of structs replacing values over itself

查看:20
本文介绍了替换自身值的结构数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以我有下面的代码,我只是从文件中提取各种东西并将它们输入到结构数组中,它最初看似"有效,但是当我在完成文件后去打印它时它似乎用最后一个值替换了所有课程和名称,奇怪的是这不会发生在整数(成绩)上,成绩确实被正确输入.

Ok so I have the below code and I am just pulling various things from a file and inputing them in an array of structs, it "seemingly" works initially, BUT when I go to printing it after it is done with the file it seemed to have replaced all of the courses and names with the very last vale, oddly this doesnt happen with the integers (grades), the grades do get inputed properly.

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

struct student {
    char *name;
    char *course;
    int grade;

};

void courseSort(struct student d[20], int size);

int main(void)
{
    FILE* fp;
    char* filename = "grades.csv";
    char buffer[100];
    char* name, *class;
    char* del=",";
    int grade, i, counter=0;

    struct student d[20];

    if((fp=fopen(filename, "r"))==NULL)
    {
        printf("unable to open %s\n", filename);
        exit(1);
    }

    while(fgets(buffer, sizeof(buffer), fp) !=NULL)
    {
        name = strtok(buffer,del);
        class=strtok(NULL,del);
        grade = atoi(strtok(NULL,del));

        d[counter].name=name;
        d[counter].course=class;
        d[counter].grade=grade;
        printf("%s    %s       %d\n",d[counter].name,d[counter].course,d[counter].grade);
        counter++;
    }

    printf("\n\n\n");

    for(i=0;i<counter;i++)
        printf("%s    %s     %d\n",d[i].name,d[i].course,d[i].grade);
    courseSort(d,counter);

    fclose(fp);
 }

我不确定我做错了什么:(这一切看起来很简单,但不知道为什么它只是用最新的替换了所有内容.

I am not sure what I am doing wrong :( it all seems straightforward but not sure why it just replaces everything with the latest one.

推荐答案

strtok 返回一个指向缓冲区的指针并且不分配内存.由于您不复制字符串,因此您最终会得到许多指向同一缓冲区的指针,这些指针在循环的每次迭代中都会被覆盖.

The strtok returns a pointer to the buffer and does not allocate memory. Since you do not copy the strings, you end up with lots of pointers pointing to the same buffer that is overwritten at each iteration of the loop.

要解决此问题,您需要更改循环以使用 strdup 复制字符串:

To fix this, you need to change your loop to copy the strings using strdup:

while(fgets(buffer, sizeof(buffer), fp) != NULL)
{
    d[counter].name = strdup(strtok(buffer, del));
    d[counter].course = strdup(strtok(NULL, del));
    d[counter].grade = atoi(strtok(NULL, del));
    counter++;
}

一旦你不再需要字符串,不要忘记用 free 返回分配的内存:

Don't forget to return the allocated memory with free once you no longer need the strings:

for (i = 0; i < counter; i++) {
   free(d[i].name);
   free(d[i].course);

   d[i].name = NULL;
   d[i].course = NULL;
}

请注意,strdup 是 POSIX1.2001 标准的一部分,而不是 C89 的一部分.如果它不可用,你必须自己重新实现它(很容易):

Note that strdup is part of POSIX1.2001 standard, not part of C89. If it is not available, you'll have to re-implement it yourself (quite easy):

char *my_strdup(const char *str) {
  char *copy;
  size_t len = strlen(str) + 1;
  if (len == 0) return NULL;
  copy = (char *)malloc(len);
  if (copy == NULL) return NULL;
  memcpy(copy, str, len);
  return copy;
}

这篇关于替换自身值的结构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆