C++结构体指针数组操作问题:实现打印功能及赋值疑惑
问题分析与修复方案
先拆解你遇到的核心问题:Trips数组元素为空、遍历打印失效,根源在于newTrip函数的致命错误,同时Test函数和遍历逻辑也存在问题。咱们一步步来解决:
1. 修复newTrip函数的关键错误
你的newTrip函数存在多处逻辑错误,导致无法生成有效的TRIP指针:
- 错误返回
0而非创建好的结构体指针 - 参数变量名不匹配(
ka写成了k) - 结构体成员笔误(
z->nazev应为z->name)
修复后的代码:
// 全局变量,用于计数行程数量(需提前声明) int numberOfTrips = 0; TRIP* newTrip(const char *n, const char *de, int ka, Date& dat) { TRIP* z = new TRIP; z->number = ++numberOfTrips; z->date = dat; // 为name分配内存并拷贝字符串 z->name = new char[strlen(n) + 1]; strcpy_s(z->name, strlen(n) + 1, n); // 为destination分配内存并拷贝字符串 z->destination = new char[strlen(de) + 1]; strcpy_s(z->destination, strlen(de) + 1, de); z->kapacity = ka; // 修复参数名错误 return z; // 返回创建好的结构体指针 };
2. 修复getInfo的缓冲区截断问题
getInfo里的snprintf缓冲区仅设为10字节,会导致行程信息被截断,改成使用缓冲区总大小:
char *getInfo(TRIP *z) { char *res; char pom[100]; if (z != NULL) { // 使用sizeof(pom)确保缓冲区足够容纳所有信息 snprintf(pom, sizeof(pom), "%d %s %s", z->number, z->name, z->destination); res = new char[strlen(pom) + 1]; strcpy_s(res, strlen(pom) + 1, pom); // 需包含字符串终止符的空间 return res; } else return NULL; };
3. 修正Test函数与遍历逻辑
Test函数里的numberOfTrips++会导致计数重复增加(newTrip内部已经自增过),造成数组索引错位:
void Test() { // 去掉此处的numberOfTrips++,避免重复计数 Trips[numberOfTrips] = newTrip("Japan", "Tokio", 30, Date(1, 6, 2018)); }
主函数的遍历循环要避免越界,且需判断空指针:
int main() { // 初始化数组所有元素为NULL,防止野指针 for (int i = 0; i < 20; i++) { Trips[i] = NULL; } Test(); // 遍历所有有效行程 for(int i = 0; i < numberOfTrips; i++) { if (Trips[i] != NULL) { // 跳过空指针,避免崩溃 printTrip(Trips[i]); } } return 0; }
4. 实现手动输入新增行程功能
编写一个函数从控制台读取用户输入,调用newTrip添加到数组:
void addTripManually() { if (numberOfTrips >= 20) { printf("行程数量已达上限(20个),无法新增!\n"); return; } char name[50], dest[50]; int kap; int day, month, year; printf("请输入行程名称:"); scanf("%s", name); printf("请输入目的地:"); scanf("%s", dest); printf("请输入容量:"); scanf("%d", &kap); printf("请输入日期(日 月 年):"); scanf("%d %d %d", &day, &month, &year); Date inputDate(day, month, year); Trips[numberOfTrips] = newTrip(name, dest, kap, inputDate); printf("行程新增成功!\n"); }
在主函数中调用即可使用手动添加功能:
int main() { for (int i = 0; i < 20; i++) { Trips[i] = NULL; } Test(); addTripManually(); // 调用手动添加函数 for(int i = 0; i < numberOfTrips; i++) { if (Trips[i] != NULL) { printTrip(Trips[i]); } } return 0; }
额外提示
- 程序结束前记得释放内存:遍历Trips数组,先释放每个TRIP的
name和destination,再释放TRIP本身,避免内存泄漏。 - 确保
Date结构体有正确的构造函数,能接收日、月、年参数。 - 使用
strcpy_s时,第二个参数必须是目标缓冲区的总大小(包含字符串终止符)。
内容的提问来源于stack exchange,提问作者Meteor2142
相关产品推荐
相关产品推荐

