在结构中创建动态列表

Creating a dynamic list within a struct

我正在尝试创建一个包含结构的动态列表。现在我有了第一个为一个人存储信息的结构。另一个结构包含第一个结构,如下所示:

Tried my best to visualize it 

employeeRegister
----------------          |-------|------| 
registerE   ------------> |city---|city--|
----------------          |London |Japan-|
numberOfemployee          |pin----|pin---|
----------------          |0101010|101010|
------|2|-------          |phone--|phone-|
                          |SAb123-|APPI20|

现在我的问题是我已经对它进行了编码,它可以工作,但不像提供的图像那样以正确的方式工作。

代码:

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

struct personalInfo {
    char city[20];
    int pin;
    char phone[14];
};

struct employeeRegister {
    struct personalInfo registerE;
    int numberOfemployee;
};

struct employeeRegister *allocateMemory(struct employeeRegister *oldMemory, int nrOfadd);
void addding(struct employeeRegister *addressToAdd, int *nrOfadd);
void printList(struct employeeRegister *allemp, int nrOfadd);

int main(void)
{
    struct employeeRegister *employee = NULL;
    int choice;
    int nrOfaddress = 0;
    do
    {
        printf("\n1 - add employee");
        printf("\n2 - print employee list");
        printf("\n3 - exit");
        printf("\nWhat do you want to do? ");
        scanf("%d", &choice);
        while (getchar() != '\n');

        switch (choice)
        {
        case 1:
            employee = allocateMemory(employee, nrOfaddress);
            if (employee == NULL)
                break;
            addding(&employee[nrOfaddress], &nrOfaddress);
            break;
        case 2:
            printList(employee, nrOfaddress);
            break;
        case 3:
            printf("Ending!\n");
            free(employee);
            employee = NULL;
            break;
        default:
            printf("Invalid input\n");
            break;
        }
    } while (choice != 3);
    return 0;
}

struct employeeRegister *allocateMemory(struct employeeRegister *oldMemory, int nrOfadd)
{
    struct employeeRegister *tempurary;
    if (nrOfadd == 0)
        tempurary = (struct employeeRegister *)calloc(1, sizeof(*tempurary));
    else
        tempurary = (struct employeeRegister *)realloc(oldMemory, sizeof(*tempurary)*(nrOfadd + 1));

    return tempurary;
}

void addding(struct employeeRegister *addressToAdd, int *nrOfadd)
{
    printf("City: ");
    fgets(addressToAdd->registerE.city, 20, stdin);
    addressToAdd->registerE.city[strlen(addressToAdd->registerE.city) - 1] = '[=11=]';
    do
    {
        printf("Pin: ");
        fflush(stdin);
    }
    while ((scanf("%d", &addressToAdd->registerE.pin) != 1));
    while (getchar() != '\n');
    printf("Phone type: ");
    fgets((addressToAdd->registerE.phone), 14, stdin);
    addressToAdd->registerE.phone[strlen(addressToAdd->registerE.phone) - 1] = '[=11=]';
    (*nrOfadd)++;
    addressToAdd->numberOfemployee = *nrOfadd;
}

void printList(struct employeeRegister *allemp, int nrOfadd)
{
    for(int i = 0; i < nrOfadd; i++)
    {
        printf("%d. %-15s%-5.1d%s\n", i + 1, allemp[i].registerE.city,
               allemp[i].registerE.pin, allemp[i].registerE.phone);
    }
}

当我调试代码时,我得到这个:

employeeRegister                            employeeRegister
----------------           |-------|        ----------------           |-------|
registerE   ------------>  |city---|        registerE   ------------>  |city---|
 ----------------          |London |        ----------------           |London |
numberOfemployee           |pin----|        numberOfemployee           |pin----|
----------------           |0101010|        ----------------           |0101010|
------|1|-------           |phone--|        ------|2|-------           |phone--|
                           |SAb123-|                                   |SAb123-|

当我 运行 codeblocks 中的代码时,命令提示符中的一切看起来都很好,但如您所见,事实并非如此。我将如何编辑我的代码以获得第一张图片的结果?

第一次发帖,有什么不对的地方请告诉我。

您的代码当前正在做的是创建一个 struct employeeRegister 数组,每个数组包含一个员工。

您需要将 struct employeeRegisterregisterE 成员更改为指针,以便它可以指向数组:

struct employeeRegister {
    struct personalInfo *registerE;
    int numberOfemployee;
};

然后创建该结构的单个实例。当您随后为更多员工分配内存时,您将添加到 registerE 指向的内存。

那么完整的修改代码如下:

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

struct personalInfo {
    char city[20];
    int pin;
    char phone[14];
};

struct employeeRegister {
    struct personalInfo *registerE;
    int numberOfemployee;
};

void allocateMemory(struct employeeRegister *allemp);
void addding(struct employeeRegister *allemp);
void printList(struct employeeRegister *allemp);

int main(void)
{
    struct employeeRegister employee = { NULL, 0 };
    int choice;
    do
    {
        printf("\n1 - add employee");
        printf("\n2 - print employee list");
        printf("\n3 - exit");
        printf("\nWhat do you want to do? ");
        scanf("%d", &choice);
        while (getchar() != '\n');

        switch (choice)
        {
        case 1:
            allocateMemory(&employee);
            if (employee.registerE == NULL)
                break;
            addding(&employee);
            break;
        case 2:
            printList(&employee);
            break;
        case 3:
            printf("Ending!\n");
            free(employee.registerE);
            employee.registerE = NULL;
            break;
        default:
            printf("Invalid input\n");
            break;
        }
    } while (choice != 3);
    return 0;
}

void allocateMemory(struct employeeRegister *allemp)
{
    struct personalInfo *tempurary;
    tempurary = realloc(allemp->registerE, sizeof(*tempurary)*(allemp->numberOfemployee + 1));

    allemp->registerE = tempurary;
}

void addding(struct employeeRegister *allemp)
{
    printf("City: ");
    fgets(allemp->registerE[allemp->numberOfemployee].city, 20, stdin);
    allemp->registerE[allemp->numberOfemployee].city[strlen(allemp->registerE[allemp->numberOfemployee].city) - 1] = '[=11=]';
    printf("Pin: ");
    while ((scanf("%d", &allemp->registerE[allemp->numberOfemployee].pin) != 1))
    {
        while (getchar() != '\n');
        printf("Pin: ");
    }
    while (getchar() != '\n');
    printf("Phone type: ");
    fgets((allemp->registerE[allemp->numberOfemployee].phone), 14, stdin);
    allemp->registerE[allemp->numberOfemployee].phone[strlen(allemp->registerE[allemp->numberOfemployee].phone) - 1] = '[=11=]';
    allemp->numberOfemployee++;
}

void printList(struct employeeRegister *allemp)
{
    for(int i = 0; i < allemp->numberOfemployee; i++)
    {
        printf("%d. %-15s%-5.1d%s\n", i + 1, allemp->registerE[i].city,
               allemp->registerE[i].pin, allemp->registerE[i].phone);
    }
}

与这些更改相关的一些附加说明:

  • 不要强制转换 malloc 系列函数的 return 值,因为这会隐藏其他错误。
  • fflush(stdin) 在某些实现上会导致未定义的行为,因此最好避免它并使用 getchar 循环来清除输入缓冲区。

另一种处理方法是使用 'header, data' 模式:

从这里开始:

struct employeeRegister {
    struct personalInfo registerE;
    int numberOfemployee;
};

现在,更改它,使您的 registerE 成为最后一个元素(因为它增长了):

struct employeeRegister {
    int numberOfemployee;
    struct personalInfo registerE;
};

分配时,使用:malloc( sizeof(struct employeeRegister) + sizeof(struct personalInfo)*(nrOfAdd-1)

这样您就可以按原样循环:

struct personInfo * person = &allemp->registerE;
for (i = 0; i < allEmp->numberOfEmployee; i++) {
    // do something with person
    person++;
}

这与您的图表非常匹配,其中:

    +-------+--------+--------------------+
    | header|Person0 |Person1 .. PersonN  |
    +-------+--------+--------------------+