You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

结构体嵌套成员引用及动态数组扩容等C语言问题求助

员工注册表程序问题求助

结构体定义

typedef struct DOB {
    int month;
    int day;
    int year;
} Birthdate;

typedef struct EmployeeInfo {
    int empID;
    char *firstName;
    char *lastName;
    Birthdate date;
    double salary;
} Employee;

主函数代码

int main() {
  //create the array of Items
  Employee * employeeRecord = (Employee * ) malloc(N * sizeof(Employee));
  Birthdate * birthRecord = (Birthdate * ) malloc(N * sizeof(Birthdate));
  int empID;
  double salary;
  Employee Employee;
  Birthdate Birthdate;
  char opt;
  while (1) {
    dispayMenu();
    printf("Enter your Choice: ");
    scanf(" %c",&opt);
    switch(opt) {
        case 'i':
            printf("\nEnter empID: ");
            scanf("%d", & Employee.empID);
            printf("Enter firstName: ");
            scanf("%s", Employee.firstName);
            printf("Enter lastName: ");
            scanf("%s", & Employee.lastName);
            printf("Enter Date of Birth (month/day/year format): ");
            scanf("%d-%d-%d", &Employee.date.month,&Employee.date.day,&Employee.date.year);
            printf("Enter Employee salary: ");
            scanf("%lf", & Employee.salary);
            insertItem(employeeRecord, Employee);
            break;
        case 'u':
            printf("\nEnter empID to update: ");
            scanf("%d", & empID);
            updateItem(employeeRecord, empID);
            break;
        case 's':
            printf("\nEnter empID to search: ");
            scanf("%d", &empID);
            searchItem(employeeRecord, empID);
            break;
        case 'd':
            printData(employeeRecord);
            break;
        case 'q':
            quit(employeeRecord);
            break;
        default:
            printf("%c is not a valid choice", opt);
    }
  }
}

核心问题

  1. 如何动态更新员工数组的大小?当前出现段错误,不想使用全局变量,不知如何在main中维护插入计数;
  2. 在updateItem函数中,如何正确访问嵌套的Birthdate成员修改出生日期?当前出现类型不匹配错误,updateItem函数代码如下:
void updateItem(Employee * employeeRecord, int empID) {
  int i;
  char chng;
  for (i = 0; i < current_size; i++)
  {
      if (employeeRecord[i].empID == empID)
      {
          printf("What data do you wish to update?: ");
          scanf(" %c", &chng);
          switch (chng)
          {
          case '1':
              printf("\nEnter new First Name: ");
              scanf("%s", &Employee.firstName);
              break;
          case '2':
              printf("\nEnter new Last Name: ");
              scanf("%s", &Employee.lastName);
              break;
          case '3':
              printf("\nEnter new Date of Birth: ");
              // scanf("%d", &empID);
              // searchItem(employeeRecord, empID);
              break;
          case '4':
              printf("\nEnter new salary: ") break;
          case '5':
              printf("\nReturning to main menu.");
              break;
          default:
              printf("%c is not valid, try it again.", opt);
          }
      }
    break;
  }
  else{
  printf("Employee Not Found");
}
}

此外还存在函数隐式声明与类型不匹配的问题。


解决方案

1. 动态维护员工数组大小与插入计数

不用全局变量,在main中直接维护两个变量:current_count(已插入员工数)和current_capacity(当前数组容量),插入时通过realloc动态扩容:

修改main函数变量定义

int main() {
    int current_count = 0;
    int current_capacity = N;
    Employee *employeeRecord = malloc(current_capacity * sizeof(Employee));
    // 无需单独分配birthRecord,Employee结构体已包含Birthdate成员,删除该行
    int empID;
    double salary;
    Employee newEmployee; // 变量名避免与类型重名,防止混淆
    char opt;
    // ... 后续菜单逻辑
}

重写insertItem函数

传入current_count和current_capacity的指针,方便内部修改,同时注意为字符串成员分配内存:

void insertItem(Employee **employeeRecord, Employee newEmp, int *current_count, int *current_capacity) {
    // 检查是否需要扩容
    if (*current_count >= *current_capacity) {
        *current_capacity *= 2; // 通常扩容为原容量的2倍
        *employeeRecord = realloc(*employeeRecord, *current_capacity * sizeof(Employee));
        if (*employeeRecord == NULL) {
            perror("realloc failed");
            exit(EXIT_FAILURE);
        }
    }
    // 复制员工数据,注意为字符串分配内存
    (*employeeRecord)[*current_count].empID = newEmp.empID;
    (*employeeRecord)[*current_count].firstName = malloc(strlen(newEmp.firstName) + 1);
    strcpy((*employeeRecord)[*current_count].firstName, newEmp.firstName);
    (*employeeRecord)[*current_count].lastName = malloc(strlen(newEmp.lastName) + 1);
    strcpy((*employeeRecord)[*current_count].lastName, newEmp.lastName);
    (*employeeRecord)[*current_count].date = newEmp.date;
    (*employeeRecord)[*current_count].salary = newEmp.salary;
    (*current_count)++;
}

修改main中的插入调用

// 先临时存储输入的字符串,避免未分配内存导致段错误
char tempFirstName[50], tempLastName[50];
printf("Enter firstName: ");
scanf("%49s", tempFirstName);
newEmployee.firstName = malloc(strlen(tempFirstName) + 1);
strcpy(newEmployee.firstName, tempFirstName);

printf("Enter lastName: ");
scanf("%49s", tempLastName);
newEmployee.lastName = malloc(strlen(tempLastName) + 1);
strcpy(newEmployee.lastName, tempLastName);

// 调用insertItem
insertItem(&employeeRecord, newEmployee, &current_count, &current_capacity);

2. 正确访问嵌套Birthdate成员修改出生日期

修正updateItem中的语法错误、变量未定义问题,正确访问结构体成员:

void updateItem(Employee *employeeRecord, int empID, int current_count) {
    int i;
    char chng;
    for (i = 0; i < current_count; i++) {
        if (employeeRecord[i].empID == empID) {
            printf("What data do you wish to update?: \n");
            printf("1. First Name\n2. Last Name\n3. Date of Birth\n4. Salary\n5. Return to menu\n");
            scanf(" %c", &chng);
            switch (chng) {
                case '1': {
                    char temp[50];
                    printf("\nEnter new First Name: ");
                    scanf("%49s", temp);
                    free(employeeRecord[i].firstName); // 释放旧内存
                    employeeRecord[i].firstName = malloc(strlen(temp) + 1);
                    strcpy(employeeRecord[i].firstName, temp);
                    break;
                }
                case '2': {
                    char temp[50];
                    printf("\nEnter new Last Name: ");
                    scanf("%49s", temp);
                    free(employeeRecord[i].lastName);
                    employeeRecord[i].lastName = malloc(strlen(temp) + 1);
                    strcpy(employeeRecord[i].lastName, temp);
                    break;
                }
                case '3':
                    printf("\nEnter new Date of Birth (month/day/year): ");
                    scanf("%d-%d-%d", &employeeRecord[i].date.month, &employeeRecord[i].date.day, &employeeRecord[i].date.year);
                    break;
                case '4':
                    printf("\nEnter new salary: ");
                    scanf("%lf", &employeeRecord[i].salary);
                    break;
                case '5':
                    printf("\nReturning to main menu.");
                    break;
                default:
                    printf("%c is not valid, try it again.\n", chng);
                    break;
            }
            return; // 找到目标员工后直接返回
        }
    }
    printf("Employee Not Found\n");
}

修改main中的更新调用

updateItem(employeeRecord, empID, current_count);

3. 解决函数隐式声明与类型不匹配问题

  • 在main函数上方添加所有自定义函数的原型,确保调用前声明:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 结构体定义
typedef struct DOB {
    int month;
    int day;
    int year;
} Birthdate;

typedef struct EmployeeInfo {
    int empID;
    char *firstName;
    char *lastName;
    Birthdate date;
    double salary;
} Employee;

// 函数原型
void dispayMenu(void);
void insertItem(Employee **, Employee, int *, int *);
void updateItem(Employee *, int, int);
void searchItem(Employee *, int, int);
void printData(Employee *, int);
void quit(Employee *, int);
  • 确保所有函数参数类型与调用一致,比如searchItem、printData都需要传入current_count来控制遍历范围;
  • 完善quit函数,释放所有动态分配的内存:
void quit(Employee *employeeRecord, int current_count) {
    for (int i = 0; i < current_count; i++) {
        free(employeeRecord[i].firstName);
        free(employeeRecord[i].lastName);
    }
    free(employeeRecord);
    exit(EXIT_SUCCESS);
}

内容的提问来源于stack exchange,提问作者CortadoLover

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:35:37