结构体数组嵌套结构体数组可行吗?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
相关产品推荐
相关产品推荐

