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

C语言中结构体数组元素赋值异常问题求助

问题分析与修复方案

核心问题:数组元素访问错误

你打印订单和计算总价时,错误地始终访问结构体数组的第一个元素:

  • 打印时的currentOder->prod->name等价于currentOder->prod[0].name,所以所有行都显示第一个商品的信息
  • 计算总价的循环里currentOder->prod->prize同样只累加第一个商品的价格

其他次要问题

  1. prodAmount递增时机错误:无论用户输入的是不是有效选项(比如输入字母),都会执行currentOder->prodAmount++,导致数组中出现未初始化的无效元素。
  2. total变量作用域问题:循环内每次重置total为0,最后打印的total不是最终订单的总价。
  3. 输入处理缺陷:while((option = getchar()) == '\n');无法正确处理多字符输入,会导致后续输入异常。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
    char name[12];
    float prize;
}PRODUCT;

typedef struct{
    unsigned prodAmount;
    unsigned orderNumber;
    PRODUCT prod[10];
}ORDER;

void menu(ORDER*);

int main()
{
    ORDER currentOrder = {0}; // 直接初始化prodAmount为0,更简洁
    menu(&currentOrder);
    return 0;
}

void menu(ORDER* currentOder){
    char option;
    float total;

    do{
        total = 0;
        // 修复总价计算:遍历每个商品
        for(int i = 0; i < currentOder->prodAmount; i++){
            total += currentOder->prod[i].prize;
        }

        system("clear");
        printf("Welcome!\n");
        printf("What would you like today?\n");
        printf("1-. BURGER      3.99$\n");
        printf("2-. CHIPS       0.99$\n");
        printf("3-. DRINK       1.99$\n");
        printf("4-. 6 NUGGETS   2.99$\n");
        printf("5-. ICE CREAM   2.99$\n");
        printf("6-. MENU        5.99$\n");
        printf("0-. PAY\n");
        printf("Products:   %u\n", currentOder->prodAmount); // 用%u匹配unsigned类型
        printf("TOTAL:      %.2f$\n", total); // 用%.2f显示两位小数更合理

        // 修复输入处理:跳过空白字符后读取单个字符
        scanf(" %c", &option);

        int validOption = 0;
        switch (option){
            case '1':
                strcpy(currentOder->prod[currentOder->prodAmount].name, "Hamburger");
                currentOder->prod[currentOder->prodAmount].prize = 3.99;
                validOption = 1;
                break;
            case '2':
                strcpy(currentOder->prod[currentOder->prodAmount].name, "Chips");
                currentOder->prod[currentOder->prodAmount].prize = 0.99;
                validOption = 1;
                break;
            case '3':
                strcpy(currentOder->prod[currentOder->prodAmount].name, "Drink");
                currentOder->prod[currentOder->prodAmount].prize = 1.99;
                validOption = 1;
                break;
            case '4':
                strcpy(currentOder->prod[currentOder->prodAmount].name, "Nuggets");
                currentOder->prod[currentOder->prodAmount].prize = 2.99;
                validOption = 1;
                break;
            case '5':
                strcpy(currentOder->prod[currentOder->prodAmount].name, "Ice cream");
                currentOder->prod[currentOder->prodAmount].prize = 2.99;
                validOption = 1;
                break;
            case '6':
                strcpy(currentOder->prod[currentOder->prodAmount].name, "Menu");
                currentOder->prod[currentOder->prodAmount].prize = 5.99;
                validOption = 1;
                break;
            case '0':
                // 支付选项,不增加商品数量
                break;
            default:
                printf("Invalid option! Press enter to continue...");
                // 清空输入缓冲区的剩余字符
                while(getchar() != '\n');
                getchar();
                break;
        }

        // 只有输入有效商品选项时,才增加商品数量
        if(validOption && currentOder->prodAmount < 10){
            currentOder->prodAmount++;
        }

    }while(option != '0' && currentOder->prodAmount < 10);

    system("clear");
    printf("Your order:\n");
    total = 0;
    // 修复打印:遍历每个商品,访问对应索引的元素
    for(int i = 0; i < currentOder->prodAmount; i++){
        printf("%s\t%.2f$\n", currentOder->prod[i].name, currentOder->prod[i].prize);
        total += currentOder->prod[i].prize;
    }
    printf("TOTAL: %.2f$\n", total);
}

关键修改说明

  • 数组访问:所有涉及prod数组的操作都加上索引[i],确保访问对应位置的元素
  • 商品数量递增:仅在用户选择有效商品选项时才执行prodAmount++,避免无效元素
  • 输入处理:改用scanf(" %c", &option)跳过空白字符,同时处理无效输入时清空缓冲区
  • 格式化输出:用%.2f显示价格,符合货币的常规显示方式,用%u匹配unsigned类型的prodAmount
  • 总价计算:在打印订单前重新计算一次,确保显示的是最终总价

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:25:18