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

超市界面商品价格及会员折扣功能故障技术问询

问题分析与修复方案

核心问题梳理

  • 数组传参错误:读取客户姓名时,scanf("%s",&name) 里的name本身就是数组首地址,加&属于多余操作,会导致未定义行为。
  • 输入缓冲区残留问题:
    • 输入姓名后,换行符会留在输入流里,后续读取会员类型的scanf会直接读这个换行符,让membershiptype变成换行符,触发switch的默认分支返回-1。
    • 原代码里scanf("%c\n",&membershiptype)的写法错误,\n会强制要求输入流里必须有换行符,反而加重了缓冲区问题。
  • 折扣判断逻辑不匹配:getDiscountPercent在会员类型非法时返回-1,但主函数里判断if (discount==1)才跳转重新输入,条件对不上,导致非法类型无法触发重新输入。
  • 未定义行为调用:fflush(stdin)是C标准未定义的操作,不同编译器表现不一样,不能用来清空输入缓冲区。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#jeremiahtask4
int getDiscountPercent(char);

int main() // 标准C要求main必须返回int类型
{
    float itemprice, discountedprice, totalpurchase = 0.00, totalafterdis = 0.00;
    int discount, itemnum = 0;
    char membershiptype, additem = 'Y', name[20];

    printf("	Suria Supermarket\n");
    printf("\nEnter customer name:");
    scanf("%s", name); // 去掉多余的&,数组名直接作为首地址传递

    printf("\nEnter membership type:");
reenter:
    // 前面加空格,自动跳过输入流里的空白字符(换行、空格等)
    scanf(" %c", &membershiptype);

    discount = getDiscountPercent(membershiptype);
    if (discount == -1) // 匹配函数返回的非法值,触发重新输入
        goto reenter;

    do {
        itemnum++;
        printf("\nItem %d", itemnum);
        printf("\nEnter item price:");
        scanf("%f", &itemprice);
        discountedprice = itemprice * (100 - discount) / 100.00;
        printf("\n\nDiscount(%%):%d", discount);
        printf("\nDiscounted price:%.2f\n", discountedprice);

        printf("\n\nAdd items (Y/N):");
        // 用循环读取到换行符,安全清空缓冲区,替代fflush(stdin)
        while (getchar() != '\n');
        scanf("%c", &additem);

        totalpurchase += itemprice;
        totalafterdis += discountedprice;
    } while (additem == 'Y' || additem == 'y');

    printf("\n	*** Purchase Details ***");
    printf("\nCustomer Name:%s", name);
    printf("\nNumber of items is:%d", itemnum);
    printf("\nTotal purchase:%.2f", totalpurchase);
    printf("\nAmount to pay:%.2f\n", totalafterdis);

    return 0; // 标准main函数需要返回值
}

int getDiscountPercent(char membershiptype)
{
    int discount; // 删掉函数内不必要的冗余变量声明

    switch(membershiptype)
    {
        case 'p': case 'P': discount = 30; break;
        case 'g': case 'G': discount = 20; break;
        case 's': case 'S': discount = 10; break;
        case 'x': case 'X': discount = 0; break;
        default: discount = -1; // 去掉多余的空语句
    }
    return discount;
}

关键修复说明

  1. 数组传参修正:scanf("%s", name) 正确传递数组首地址,避免地址错误。
  2. 缓冲区处理优化:
    • 读取会员类型时,scanf(" %c", &membershiptype) 里的空格会自动跳过输入流中的空白字符,解决换行残留问题。
    • 用while (getchar() != '\n')替代fflush(stdin),安全清空输入缓冲区,符合C标准规范。
  3. 逻辑匹配修正:把if (discount==1)改成if (discount==-1),和getDiscountPercent返回的非法值匹配,确保非法会员类型会触发重新输入。
  4. 代码规范优化:补充main函数的返回值声明和返回语句,移除函数内不必要的变量声明,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:35:26