【问题标题】:Issues with nested structures and dynamic memory allocation [closed]嵌套结构和动态内存分配的问题[关闭]
【发布时间】:2021-11-08 09:34:58
【问题描述】:

我正在使用嵌套结构和动态内存分配,但遇到了问题。

我正在使用以下输入:

会员编号:1
会员姓名:A
保单编号:1

策略 ID:P1
策略类型:1
保单保费:100

但是,在我进入 P1 后,我无法输入任何其他内容。程序终止。

我遇到的另一个问题是,当我选择应该打印所有成员的选项 2 时,它无法正确显示。

即使在输入任何成员详细信息之前,如果我选择选项 2,它也会显示以下内容:

会员编号:0
会员姓名:

我想知道是否在创建动态数组时,我犯了一个错误,它实际上是在打印 member[0]。 将成员添加到数组后,然后选择选项 2,它会打印:

会员编号:1
会员姓名:A
策略 ID:(空)
保单类型:保费:100 美元

它会打印成员详细信息,但在访问该成员的策略时,这些详细信息不会打印,它会完全跳过 政策类型。

完整代码如下:

#include <malloc.h>
#include <stdio.h>

enum enumtype { Car, Health, Travel, Pet };

typedef struct policy {
        char id[4];
        enum enumtype type;
        int premium;
}pol;

typedef struct member {
    int id;
    char name[30];
    int polnum;
    pol *policy;
}mem;

mem getmember() {
    mem member;
    int i, j;

    printf("\n\nEnter member's details");
    printf("\nMember ID: ");
    scanf("%d", &member.id);
    printf("Member Name: ");
    scanf(" %s", member.name);
    printf("Requested number of policies: ");
    scanf("%d", &member.polnum);

    if (member.polnum > 0) { 
        printf("\nEnter policy details for %s", member.name);
        for (i = 0; i < member.polnum; i++) {
            printf("\nEnter details for policy %d", i + 1);
            printf("\nEnter Policy ID: ");
            scanf(" %s", member.policy->id);

            printf("\nEnter Policy Type:");
            printf("\n1 - Car");
            printf("\n2 - Health");
            printf("\n3 - Travel");
            printf("\n4 - Pet");
            printf("\n\nEnter an option: ");
            scanf("%d", &member.policy[i].type);

            while (member.policy[i].type < 1 || member.policy[i].type > 4) {
                printf("\nInvalid policy type");
                printf("\nPlease enter a number from 1 - 4: ");
                scanf("%d", &member.policy[i].type);
            }

            printf("\nEnter Premium: $");
            scanf("%d", &member.policy[i].premium);

            while (member.policy[i].premium < 0) {
                printf("Invalid premium");
                printf("\nPremium must be a positive value");
                printf("\nEnter Premium: $");
                scanf("%d", &member.policy[i].premium);
            }
        }
    }
    else
        member.policy = NULL;
    
    return member;
}

void printmember(mem* member, int memNum) {

    int i, j;

    for (i = 1; i = memNum+1; i++) { // This still doesn't print properly but I don't know why
        //printf("\nDetails for Member %d", i + 1);
        printf("\n\nMember ID: %d", member[i].id);
        printf("\nMember Name: %s", member[i].name);

        for (j = 0; j < member[i].polnum; j++) {
            printf("\nPolicy ID: %s", member[i].policy[j].id);
            printf("\nPolicy Type: ", member[i].policy[j].type);
            switch (member[i].policy[j].type) { 
            case 1:
                printf("Car");
                break;
            case 2:
                printf("Health");
                break;
            case 3:
                printf("Travel");
                break;
            case 4:
                printf("Pet");
                break;
            }
            
            printf("Premium: $%d", member[i].policy[j].premium);
        }
    }
}

int main()
{
    int choice = 0;
    int memNum = 0;
    char name[30];
    mem* member = NULL;
    member = (mem*)realloc(member, (memNum++) * sizeof(member));


    while (choice != 3) {
        
        choice = 0;
        printf("\n\t   Menu");
        printf("\n-----------------------------");
        printf("\n1 - Add new member");
        printf("\n2 - Display all members");
        printf("\n3 - Exit");
        
        printf("\n\nEnter an option: ");
        scanf("%d", &choice);
        
        switch (choice) {
        case 1:
            member = (mem*)realloc(member, (memNum + 1) * sizeof(member));
            member[memNum++] = getmember();
            break;
        case 2:
            printf("\n\nDisplaying all members");
            printmember(member, memNum);
            break;
        case 3:
            return 0;
        }
    }
}

【问题讨论】:

  • sizeof(member) -> sizeof(*member)
  • 必须 始终检查scanf返回的值。如果输入流中存在非数字值,则scanf("%d", &amp;choice); 将返回 0,并且不会修改choice 的值。如果它的值以前是 3,则代码将退出。这可能就是为什么当您认为您正在输入“1”时会看到零星退出的原因。始终检查返回值。
  • scanf(" %s", &amp;member.name); 没有宽度限制是不好的。使用scanf("%3s", &amp;member.name);
  • @WetWizard sizeof(member) 是一个指针的大小。 sizeof(*member) 是指针指向的结构的大小,是你需要的大小。
  • 问题已损坏——几乎无法修复。目前尚不清楚它应该回滚到哪个版本。鉴于损害,我将投票关闭。就目前而言(没有显示代码),它需要更多细节。

标签: arrays c structure


【解决方案1】:
typedef struct member {
    int id;
    char name[30];
    int polnum;

    struct policy {
        char id[4];
        enum enumtype type;
        int premium;
    }pol;
}mem;

您可以拥有n 成员,每个成员都可以拥有polnum 策略,但这不是这个结构所说的。该结构表示每个成员都有一个由嵌套结构表示的策略。将成员保存在数组中的外部 realloc 限制了解决方案空间。我们实际上无法做到这一点并同时使用弹性结构,所以我不必讨论如何。我们只是按照您已经知道的方式执行此操作。

typedef struct struct policy {
        char id[4];
        enum enumtype type;
        int premium;
} pol;

typedef struct member {
    int id;
    char name[30];
    int polnum;
    pol *policies;
}mem;

添加策略是这样的:

    if (member.polnum > 0) { 
        member.pol = malloc(member.polnum * sizeof(pol));
        printf("\nEnter policy details for %s", member.name);
        for (i = 0; i < member.polnum; i++) {
             //...
             scanf("%d", &member.pol[i].type);
             //...
         }
     } else {
         member.pol = NULL; // When you go to write the free memory code you will thank me
     }

在打印成员中,我们有一个非常相似的结构:

        for (j = 0; j < member[i].polnum; j++) {
            printf("\nPolicy ID: %s", member[i].pol[j].type);

管理说明:发布答案后,代码已从问题中删除。

【讨论】:

  • 所以我做了您建议的更改,但我仍然遇到一些问题,希望您能提供帮助。我已经用新代码和持续存在的问题更新了帖子。
  • @WetWizard:来自您的代码:scanf(" %s", member.policy-&gt;id);:未完全更新。无论如何,你现在有了这个想法,这只是一个调试问题。
  • 或者代码可以为策略使用灵活的数组成员。在另一个结构中定义的结构是合法的,尽管不寻常。嵌套定义也不会阻止在其他上下文中使用 struct policy 类型(这不是 C++)。
  • @JonathanLeffler:为了使用灵活的数组成员,来自 realloc 的外部数组必须是指向结构而不是结构的指针(更大的变化),所以我没有那样做。
  • 公平评论。 .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
相关资源
最近更新 更多