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

C语言购物清单程序addItem函数实现及容量限制问题咨询

问题:购物清单程序addItem函数实现错误,需限制最大5个商品

我正在开发一款具备商品添加、删除、打印、编辑、保存功能的购物清单程序,目前卡在addItem函数的实现环节。该函数接收指向main中定义的ShoppingList结构体的指针,需要直接修改原列表:

  • 获取商品名称、数量(非正数需提示重输)、单位
  • 将商品添加至列表末尾,维护length字段
  • 最多添加5个商品

当前代码错误使用malloc,咨询如何正确限制列表容量为5个商品,以下是完整代码:


main.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include "ShoppingList.h"

int main(void)
{
    struct ShoppingList shoppingList;
    shoppingList.length = 0; // 初始时购物清单为空

    int option;

    do
    {
        printf("\n\n欢迎使用购物清单管理器!\n");
        printf("=====================================\n\n");

        printf("1. 添加商品\n");
        printf("2. 显示购物清单\n");
        printf("3. 删除商品\n");
        printf("4. 修改商品\n");
        printf("5. 保存清单\n");
        printf("6. 加载清单\n");
        printf("7. 退出\n");

        printf("请选择操作:");
        scanf("%d", &option);

        switch (option)
        {
        case 1: addItem(&shoppingList); break;
        case 2: printList(&shoppingList); break;
        case 3: removeItem(&shoppingList); break;
        case 4: editItem(&shoppingList); break;
        case 5: saveList(&shoppingList); break;
        case 6: loadList(&shoppingList); break;
        case 7: break;
        default:
            printf("请输入1-7之间的数字");
        }
    } while (option != 7);

    return 0;
}

ShoppingList.c

#define _CRT_SECURE_NO_WARNINGS
#include"ShoppingList.h"
#include<stdio.h>
#include<stdlib.h> // 用于malloc()和free()

void addItem(struct ShoppingList* list)
{
    list = (struct ShoppingList*)malloc(sizeof(struct ShoppingList) * 5);
    
    printf("商品名称:");
    scanf("%s", list->itemList[list->length].productName);

    do
    {
        printf("输入数量:");
        scanf("%f", &list->itemList[list->length].amount);

        if (list->itemList[list->length].amount <= 0.0)
        {
            printf("输入无效。\n");
        }

    } while (list->itemList[list->length].amount <= 0.0);

    printf("输入单位:");
    scanf("%s", list->itemList[list->length].unit);

    list->length++;
}

void printList(struct ShoppingList *list)
{
    int i;
    
    printf("\n名称:\t数量:\t单位:\n\n");
    
    for (i = 0; i < list->length; i++) {
        printf("%s\t%d\t%s\n", list->itemList[i].productName, list->itemList[i].amount, list->itemList[i].unit);
    }

    printf("\n\n");
}

void editItem(struct ShoppingList *list)
{

}

void removeItem(struct ShoppingList *list)
{

}

void saveList(struct ShoppingList *list)
{

}

void loadList(struct ShoppingList* list)
{
    
}

ShoppingList.h

#ifndef SHOPPING_LIST_H
#define SHOPPING_LIST_H

// 结构体定义
struct GroceryItem
{
    char productName[20];
    float amount;
    char unit[10];
};

struct ShoppingList
{
    int length;
    struct GroceryItem itemList[5];
};

// 函数声明
void addItem(struct ShoppingList *list);
void printList(struct ShoppingList *list);
void editItem(struct ShoppingList *list);
void removeItem(struct ShoppingList *list);
void saveList(struct ShoppingList *list);
void loadList(struct ShoppingList* list);

#endif

修复方案

核心问题分析

你的ShoppingList结构体已经在头文件中定义了固定大小为5的itemList数组,且main函数中直接在栈上声明了ShoppingList变量,完全不需要用malloc分配内存——当前addItem里的malloc会覆盖传入的指针,导致所有修改都作用在临时分配的内存上,既不会同步到原列表,还会造成内存泄漏。

修正后的addItem函数

void addItem(struct ShoppingList* list)
{
    // 先检查列表是否已满
    if (list->length >= 5) {
        printf("购物清单已满,最多只能添加5个商品!\n");
        return;
    }

    printf("商品名称:");
    // 注意:scanf("%s")会截断空格,若要支持带空格的商品名需替换为fgets
    scanf("%s", list->itemList[list->length].productName);

    float inputAmount;
    do
    {
        printf("输入数量:");
        scanf("%f", &inputAmount);

        if (inputAmount <= 0.0)
        {
            printf("输入无效,请输入正数!\n");
        }

    } while (inputAmount <= 0.0);
    // 确认输入有效后再赋值给结构体
    list->itemList[list->length].amount = inputAmount;

    printf("输入单位:");
    scanf("%s", list->itemList[list->length].unit);

    // 最后更新列表长度
    list->length++;
}

额外小问题修复

printList函数中打印amount时用了%d格式符,但amount是float类型,应该用%f(或%.2f保留两位小数):

printf("%s\t%.2f\t%s\n", list->itemList[i].productName, list->itemList[i].amount, list->itemList[i].unit);

关键要点总结

  • 利用ShoppingList的length字段和固定数组的大小(5)判断是否已满,满了就直接拒绝添加
  • 必须移除addItem中的malloc代码,直接操作传入的指针指向的原结构体
  • 输入数量时可以先存在临时变量里,避免无效值提前污染结构体
  • 注意格式化输出的类型匹配,避免打印错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:30:48