结构动态分配 [英] structure dynamic allocation

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

问题描述

Hello guys

我正在尝试以一种我不知道所需尺寸的方式制作一系列结构。

我的目标是获取所有信息从一个文本文件中,并将每一行放在不同的结构中。

i考虑在while循环中使用realloc,如果我没有到达文件的末尾,我将重新分配一个结构。

我在函数InputData中需要帮助。

提前致谢

Hello guys
I'm trying to make an array of structure in a way that i dont know the wanted size.
My goal is to take all the information from a text file and put each line in different structure.
i thought about using realloc in a while loop and if i didnt got to the end of file i will realloc one more structure.
I need help in the function "InputData".
Thanks in advance


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

typedef struct
{
    char name[100];
    int** grades[2];

}student;

void Error_Msg(char*);
int InputData(student **,FILE*);
void OutputData(int,student*,FILE*);

int main()
{
    FILE *fp;
    student * arr;
    int size;

    if(!(fp=fopen("Students.txt","r")))
          Error_Msg("The input file is wrong");
    size = InputData(&arr,fp);
    
    fclose(fp);
    if(!(fp=fopen("Students.txt","w")))
        Error_Msg("The output file is wrong");
    OutputData(size,arr,fp);
    fclose(fp);
    return 0;
}


int InputData(student ** p_array, FILE * fp){
 student * temp = *p_array;
 int i=1;

 temp = (student*)malloc(sizeof(student));
 while(fscanf(fp,"%s %d %d %d",temp[i-1].name,&temp[i-1].grades[0],&temp[i-1].grades[1],&temp[i-1].grades[2])!=EOF)
 {
     temp = (student*)realloc(sizeof(student)*1);
     i++;
 }

 return i-1;
}

推荐答案

这样的事情可能适合你;



Something like this might do the trick for you;

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

typedef struct {
    char name[100];
    int gradeA;
    int gradeB;
    int gradeC;

} student;

student* read_student(FILE* file) {
    student* s = (student*)malloc(sizeof(student));

    if (fscanf(file,"%s %d %d %d", &s->name, &s->gradeA, &s->gradeB, &s->gradeC) != EOF) {
        return s;
    }
    else {
        free(s);
        return NULL;
    }
}

void print_student(student* s) {
    printf("%s %d %d %d\r\n", s->name, s->gradeA, s->gradeB, s->gradeC);
}

int main() {
    FILE* file = fopen("C:\\Temp\\grades.txt", "r");

    student* s = NULL;
    student** students;
    int count = 0;
    while((s = read_student(file))) {
        student** new_students = (student**)malloc(sizeof(student) * (count + 1));
        for(int i = 0; i < count; ++i) {
            new_students[i] = students[i];
        }

        new_students[count] = s;
        free(students);
        students = new_students;
        ++count;
    }

    fclose(file);

    for(int i = 0; i < count; ++i) {
        print_student(students[i]);
    }

    return 0;
}





而不是 realloc 我刚刚抛弃了旧列表并且每次都创建一个新的。

我建议使用某种形式的链表结构来跟踪每个学生的阅读。



希望这会有所帮助,

Fredrik



Instead of realloc I've just dumped the old list and created a new every time.
I would recommend using a some form of linked list structure to track each student read instead.

Hope this helps,
Fredrik


Realloc是一项昂贵的操作,所以在每一行上调用它会更贵,然后只需读取文件两次:一次计算行数,第二次读取这些行。







更好的解决方案是涉及文件格式变化的解决方案。在所有文件的最开头编写一些元数据部分总是一个好主意。除了其他的东西(那些文件是什么,用于编写和/或阅读它的应用程序),应该告知记录的数量。



替代方案当记录可以具有相同的大小时,方法将使用非文本(二进制)读/写模式。







我没有提到基于元数据的解决方案只有在以编程方式编写文件时才会更好。请参阅下面pasztorpisti的评论。



-SA
Realloc is expensive operation, so calling it on each line would be more expensive then simply read the file twice: one time for counting the number of lines, the second time for reading those lines.



Even better solution would be the one involving the change in file format. It's always a good idea to write some metadata part at the very beginning of all files. Among other things (what is that files for, what applications are used to write and/or read it), is should inform on the number of records.

On alternative approach would be using non-text (binary) mode of read/write, when records can have the same size.



I failed to mention that the solution based on metadata is only better when the file is written programmatically. Please see the comment by pasztorpisti below.

—SA


这篇关于结构动态分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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