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

结构体数组嵌套结构体数组可行吗?C语言代码报错求助

问题分析与解决:C语言结构体嵌套数组报错

问题背景

开发多公司管理项目,每家公司需支持多条评论(Coment)和评分(Rating),编写的结构体定义及插入评论函数运行时报错:subscripted value is neither array nor pointer nor vector,报错行是尝试通过下标访问公司评论的代码。

原结构体定义:

#define COMPANY_INITIAL_SIZE 20
#define SEARCHES_INITIAL_SIZE 20

#define TEXT_MAX_SIZE 200
#define NAME_MAX_SIZE 50
#define EMAIL_MAX_SIZE 50
#define TITLE_MAX_SIZE 50
#define ADDRESS_MAX_SIZE 70
#define LOCATION_MAX_SIZE 70
#define CATEGORY_MAX_SIZE 30

#define NIF_MIN_SIZE 100000000
#define NIF_MAX_SIZE 999999999

enum category {
    microCompany = 1, pmeCompany, macroCompany
};

enum state {
    inactive, active
};

enum searchCamp {
    nif, businessArea, nameLocation
};

enum comentState {
    hidden,visible
};

typedef struct {
    char title[TITLE_MAX_SIZE];
    char text[TEXT_MAX_SIZE];
    char userName[NAME_MAX_SIZE];
    char userEmail[EMAIL_MAX_SIZE];
    enum comentState states;
} Coment;

typedef struct {
    int nota;
    char userName[NAME_MAX_SIZE];
    char userEmail[EMAIL_MAX_SIZE];
} Rating;

typedef struct {
    int Nif;
    char name[NAME_MAX_SIZE];
    enum category categories;
    int businessAreaCode;
    enum state states;
    char address[ADDRESS_MAX_SIZE];
    char location[LOCATION_MAX_SIZE];
    int postalCode;
    int comentCounter,comentSize;
    Coment coments;
    int ratingCounter,ratingSize;
    Rating ratings;
} Company;

typedef struct {
    int counter, size;
    Company *companies;
} Companies;

原插入评论函数:

void insertComent(Companies *companies) {
    int company, nif;
    char title[TITLE_MAX_SIZE], text[TEXT_MAX_SIZE], name[NAME_MAX_SIZE], email[EMAIL_MAX_SIZE];

    nif = getInt(NIF_MIN_SIZE, NIF_MAX_SIZE, "\nNIF [9 digits]: ");

    company = verifyIfCompanyExists(*companies, nif);
    if (company != -1) {

        readString(title, TITLE_MAX_SIZE, "\nTitle: ");

        strcpy(companies->companies[company].coments[companies->companies[company].comentCounter].title, title); //<- this is the line that gives the error.

        readString(text, TEXT_MAX_SIZE, "\nTitle: ");
        strcpy(companies->companies->coments.text, text);
        readString(name, NAME_MAX_SIZE, "\nUserName: ");
        strcpy(companies->companies->coments.userName, name);
        readString(email, EMAIL_MAX_SIZE, "\nEmail: ");
        strcpy(companies->companies->coments.userEmail, email);


    }
}

错误原因

报错的核心问题是Company结构体中的coments和ratings是单个结构体实例,不是数组或指针:

  • 代码中Coment coments;定义的是一个单独的Coment变量,无法通过coments[下标]的方式访问多个元素,编译器因此抛出下标访问非法的错误。
  • 函数后续的companies->companies->coments.text写法也错误,既没有指定具体的公司索引,也没有指定评论索引。

解决方案

要实现一家公司多条评论/评分,需要将coments和ratings改为动态数组(指针),配合计数器和容量变量管理内存。

1. 修改结构体定义

新增评论/评分的初始容量宏,将Coment coments;改为Coment *coments;,Rating ratings;改为Rating *ratings;:

// 新增评论和评分的初始容量定义
#define COMENT_INITIAL_SIZE 10
#define RATING_INITIAL_SIZE 10

typedef struct {
    int Nif;
    char name[NAME_MAX_SIZE];
    enum category categories;
    int businessAreaCode;
    enum state states;
    char address[ADDRESS_MAX_SIZE];
    char location[LOCATION_MAX_SIZE];
    int postalCode;
    int comentCounter, comentSize;
    Coment *coments; // 改为指针,指向动态分配的评论数组
    int ratingCounter, ratingSize;
    Rating *ratings; // 改为指针,指向动态分配的评分数组
} Company;

2. 初始化公司的评论/评分数组

在创建新Company实例时,需要为coments和ratings分配初始内存(示例代码):

// 示例:创建新公司并初始化评论数组
Company createNewCompany() {
    Company newComp = {0};
    // 初始化评论数组
    newComp.comentSize = COMENT_INITIAL_SIZE;
    newComp.comentCounter = 0;
    newComp.coments = malloc(sizeof(Coment) * newComp.comentSize);
    // 初始化评分数组
    newComp.ratingSize = RATING_INITIAL_SIZE;
    newComp.ratingCounter = 0;
    newComp.ratings = malloc(sizeof(Rating) * newComp.ratingSize);
    // 其他字段初始化...
    return newComp;
}

3. 修改insertComent函数

修正下标访问逻辑,增加内存扩容判断(当评论数量达到当前容量时,扩容数组):

void insertComent(Companies *companies) {
    int companyIndex, nif;
    char title[TITLE_MAX_SIZE], text[TEXT_MAX_SIZE], name[NAME_MAX_SIZE], email[EMAIL_MAX_SIZE];

    nif = getInt(NIF_MIN_SIZE, NIF_MAX_SIZE, "\nNIF [9 digits]: ");
    companyIndex = verifyIfCompanyExists(*companies, nif);
    
    if (companyIndex != -1) {
        Company *targetComp = &companies->companies[companyIndex];
        int currentComentIdx = targetComp->comentCounter;

        // 检查是否需要扩容评论数组
        if (currentComentIdx >= targetComp->comentSize) {
            // 扩容为原来的2倍
            targetComp->comentSize *= 2;
            targetComp->coments = realloc(targetComp->coments, sizeof(Coment) * targetComp->comentSize);
            // 实际项目中需检查realloc是否成功
        }

        // 读取评论数据并赋值
        readString(title, TITLE_MAX_SIZE, "\nTitle: ");
        strcpy(targetComp->coments[currentComentIdx].title, title);
        
        readString(text, TEXT_MAX_SIZE, "\nText: "); // 原代码提示文字错误,修正为Text
        strcpy(targetComp->coments[currentComentIdx].text, text);
        
        readString(name, NAME_MAX_SIZE, "\nUserName: ");
        strcpy(targetComp->coments[currentComentIdx].userName, name);
        
        readString(email, EMAIL_MAX_SIZE, "\nEmail: ");
        strcpy(targetComp->coments[currentComentIdx].userEmail, email);
        
        // 设置评论状态为可见(默认)
        targetComp->coments[currentComentIdx].states = visible;
        
        // 评论计数器自增
        targetComp->comentCounter++;
    }
}

4. 注意事项

  • 动态分配的内存需要在程序结束或删除公司时用free()释放,避免内存泄漏。
  • 实际开发中要检查malloc和realloc的返回值,处理内存分配失败的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:35:58