【问题标题】:Dynamically allocating array of struct from file in C从C中的文件动态分配结构数组
【发布时间】:2017-04-24 19:34:42
【问题描述】:

我有一个我正在尝试编写的程序,它将打开一个名为 list.txt 的文件,该文件将在每一行包含一个数字、一个 ID 和一个字符串名称。该程序将读取 list.txt 文件并对 ID 编号进行排序,并将排序后的 ID 与编号和名称打印到 index.txt 文件中。我写了一个程序代码,它正在工作......

这是我的 list.txt

(编号、ID、名称)

0 3 AB
1 2 BC
2 28 DC
3 1 EF
4 13 BB
10 30 CC
11 23 FF
14 16 GG

本程序编译后按编号和名称排序ID,打印到index.txt,应该是:

(ID、编号、名称)

1 3 EF
2 1 BC
3 0 AB
13 4 BB
16 14 GG
23 11 FF
28 2 DC
30 10 CC

这是我的程序代码:

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

#define NUM_NUMBERS 9

typedef struct student
{   
    int num;
    int id;
    char name[100];
}end;

void update();
void Sort(student array[], int n); 
void load_menu();
void add(end *e);
void search(end e);
void view(end e);

FILE *fp;
FILE *f1;

int main(int argc, char** argv)
{

    load_menu();

    return 0;
}
void update()
{
    end st[15];
    int sayi[NUM_NUMBERS], number, i=0, j=0;
    fp=fopen("list.txt", "r");
    if( fp == NULL ) 
    {
        printf("File is not found at add();\n");
        exit(0);
    }
    while(!feof(fp))
    {
        fscanf(fp,"%d%d%s",&st[i].num,&st[i].id,st[i].name);
        i++;
    }
    Sort(st, NUM_NUMBERS);
    f1=fopen("index.txt", "w");
    for(int i=0; i<NUM_NUMBERS;i++)
    {
        fprintf(f1, "%d %d %s\n", st[i].id, st[i].num, st[i].name);
    }
}
void Sort(end array[], int n)
{
    int Min;
    for(int i=0; i<n-1;i++)
    {
        Min=i;
        for(int j=i+1;j<n;j++)
        {
            if(array[j].id<array[Min].id)
            {
                Min=j;
            }
        }
        end temp=array[i];
        array[i]=array[Min];
        array[Min]=temp;
    }
}
void load_menu(void)
{
    end e; 
    int choice;
    do
    {
        printf("1. Find a record given its ID value \n");
        printf("2. Add a new record to the file \n");
        printf("3. View Records\n");
        printf("4. Exit\n\n");
        printf("Please choose one: ");
        scanf("%d",&choice);
        switch(choice)
        {
            case 1:
                search(e);
                break;
            case 2: add(&e);
                    update();
                break;
            case 3: view(e);
                break;
            case 4: printf("Done.");
                return;
                break;
            default: printf("Invalid choice\n");
        }
    }while (choice != 5);
    system("cls");
} 
void add(end *e)
{
    int i=0;
    system("cls");
    fp = fopen ( "list.txt", "a" );
    if( fp == NULL ) 
    {
        printf("File is not found at add();\n");
        exit(0);
    }
    printf("\n-----Add a new record-----\n");
    printf("Enter number: ");
    scanf("%d", &e->num);
    printf("\nEnter ID : ");
    scanf("%d",&e->id);
    printf("\nEnter name: ");
    scanf("%s",e->name);
    fscanf(fp,"%d %d %s\n\n",&e->num, &e->id, e->name);
    fprintf(fp,"%d %d %s\n\n",e->num ,e->id, e->name);
    fclose(fp);
    return;
}
void search(end e)
{
    int i=0;
    int sid;
    system("cls");
    fp = fopen ("list.txt", "r");
    if(fp==NULL)
    {
        printf("File is not found at search();");
    }
    printf("\n-----Search ID-----\n");
    printf("\nEnter ID : ");
    scanf("%d",&sid);
    printf("\nNumber   ID       Name");
    while(!feof(fp))
    {
        fscanf(fp,"%d %d %s", &e.num, &e.id, &e.name);
        if(sid==e.id)
        {   
            printf("\n%d        %d        %s",e.num ,e.id, e.name);
        }
    }
    printf("\n\n");
    fclose(fp);
}
void view(end e)
{
    int i=0;
    system("cls");
    printf("\n-----list.txt-----\n");
    fp = fopen("list.txt", "r");
    if(fp == NULL)
    {
        printf("File is not found at view();\n");
        exit(0);
    }
    printf("\nNumber   ID       Name");
    printf("\n");
    while(fscanf (fp, "%d %d %s ",&e.num, &e.id, &e.name) != EOF )
    printf("\n%d        %d        %s",e.num ,e.id, e.name);
    printf("\n\n");

    printf("-----index.txt-----\n");
    f1 = fopen("index.txt", "r");
    if(fp == NULL)
    {
        printf("File is not found.\n");
        exit(0);
    }
    printf("\nNumber   ID       Name");
    printf("\n");
    while(fscanf (f1, "%d %d %s ",&e.id, &e.num, &e.name) != EOF )
    printf("\n%d        %d        %s",e.id ,e.num, e.name);
    printf("\n\n");

    fclose(fp);
    fclose(f1);
    return;
}

但是我只使用了数组,所以我需要在结构数组中动态分配来存储信息。还是不知道怎么用动态分配(malloc)。你能告诉我如何动态使用代码吗?感谢您的帮助。 (抱歉英语不好。)

【问题讨论】:

  • 即使您使用的是 C 函数,但实际上您是在使用 C++ 进行编程。
  • c++,不是c,为什么还要坚持旧的数据结构?使用std::vector
  • 对不起,我发布了错误的代码,已编辑。
  • add : fscanf(fp,"%d %d %s\n\n",&amp;e-&gt;num, &amp;e-&gt;id, e-&gt;name); 删除这个。

标签: c file dynamic malloc


【解决方案1】:

示例代码:

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

typedef struct student{   
    int num;
    int id;
    char name[100];
}end;

int cmp(void const *a, void const *b){
    const end *x = a;
    const end *y = b;
    return x->id < y->id ? -1 : x->id > y->id;
}

int main(void){
    end *st = NULL, tmp;
    FILE *fp;
    size_t i = 0, n = 0;

    fp=fopen("list.txt", "r");
    if( fp == NULL ) {
        perror("fopen at XXX");
        exit(EXIT_FAILURE);
    }
    while(3 == fscanf(fp,"%d %d %s", &tmp.num, &tmp.id, tmp.name)){
        end *temp = realloc(st, ++n * sizeof(*st));//Secure multiple records when the number of records is large
        if(temp == NULL){
            perror("realloc at XXX");
            free(st);
            exit(EXIT_FAILURE);
        }
        st = temp;
        st[i++] = tmp;
    }
    fclose(fp);

    qsort(st, n, sizeof(*st), cmp);

    fp=fopen("index.txt", "w");
    for(i = 0; i < n; ++i){
        fprintf(fp, "%d %d %s\n", st[i].id, st[i].num, st[i].name);
    }
    fclose(fp);
    free(st);
}

【讨论】:

  • 感谢您的回答和帮助,但int cmp(void const *a, void const *b){ const end *x = a; const end *y = b; return x-&gt;id &lt; y-&gt;id ? -1 : x-&gt;id &gt; y-&gt;id; }有一些错误
  • @ArkhamKnight 我认为我没有错。为什么你认为这是一个错误?
  • 不,你是对的,你的代码是正确的,但 Visual Studio 说“正在初始化”:无法从 'const void *' 转换为 'const end *'
  • @ArkhamKnight 这似乎是因为您将 C++ 用作 C。请按如下方式进行转换。 const end *x = (const end *)a; const end *y = (const end *)b;
  • 真傻,我忘了将 Source.cpp 重命名为 Source.c。非常感谢,我认为它正在工作,现在我将编写 add()、search() 等函数。感谢所有的努力。
【解决方案2】:

malloc() 返回一个指向你分配的内存的指针。参数是您要分配的内存大小,因此在您的情况下,它是“end”的大小。

你需要先声明一个指向“end”的指针,然后调用malloc()。

end * ptr = malloc(sizeof(end));

但这只是一个元素。您绝对应该查看 c 中列表的教程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-22
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 2021-10-15
    • 1970-01-01
    • 2017-04-23
    相关资源
    最近更新 更多