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

C语言点餐程序BUG:含空格菜品无法被识别的技术求助

含空格菜品无法识别的原因及修复

问题根源

两款代码的核心问题出在输入读取环节:均使用了scanf("%19s", selections[i])。%s格式符的特性是遇到空格、制表符或换行符就停止读取,因此当输入"set dosa"时,程序实际只捕获到了"set"这个子串,而非完整的菜品名称,自然无法与菜单中的"SET DOSA"匹配,导致判定为无效选项。

解决方案

要读取包含空格的完整输入,有两种常用方法:

方法1:使用fgets读取整行输入

fgets可以读取包含空格的整行内容,但会将输入末尾的换行符\n一并读取,需要手动去除该换行符,避免影响后续的字符串匹配。

方法2:使用scanf("%[^\n]")格式符

%[^\n]表示读取所有字符直到遇到换行符,但需要注意:在读取完前一个整数(numSelections)后,输入缓冲区中会残留换行符,需要先清空该换行符,否则%[^\n]会直接读取空内容。

修改后的代码示例(以第一款代码为例)

方法1:使用fgets的版本

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

const char items[5][20] = {"TEA", "COFFEE", "IDLI", "SET DOSA", "MASALA DOSA"};
int prices[5] = {15, 20, 15, 30, 40};  // Predefined prices

int findItemIndex(const char *selection) {
    for (int i = 0; i < 5; i++) {
        if (strcasecmp(selection, items[i]) == 0) {
            return i;
        }
    }
    return -1;  // Return -1 if not found
}

int main() {
    char selections[5][20];  // User inputs for selections
    int numSelections, totalBill = 0;
    
    printf("Enter the number of selections (up to 5): ");
    scanf("%d", &numSelections);
    // 清空scanf留下的换行符
    getchar();

    for (int i = 0; i < numSelections; i++) {
        printf("Enter selection %d: ", i + 1);
        // 读取整行输入,最多19个字符(留一个位置给终止符)
        fgets(selections[i], sizeof(selections[i]), stdin);
        
        // 去除末尾的换行符
        size_t len = strlen(selections[i]);
        if (len > 0 && selections[i][len-1] == '\n') {
            selections[i][len-1] = '\0';
        }

        int index = findItemIndex(selections[i]);
        if (index != -1) {
            printf("Price for %s: Rs%d/-
", selections[i], prices[index]);
            totalBill += prices[index];
        } else {
            printf("Selection %s not found in the menu.
", selections[i]);
        }
    }

    if (totalBill == 0) {
        printf("No valid selections found.
");
    } else {
        printf("The total bill payable including GST is: Rs%d/-
", totalBill);
    }

    return 0;
}

方法2:使用scanf("%[^\n]")的版本

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

const char items[5][20] = {"TEA", "COFFEE", "IDLI", "SET DOSA", "MASALA DOSA"};
int prices[5] = {15, 20, 15, 30, 40};  // Predefined prices

int findItemIndex(const char *selection) {
    for (int i = 0; i < 5; i++) {
        if (strcasecmp(selection, items[i]) == 0) {
            return i;
        }
    }
    return -1;  // Return -1 if not found
}

int main() {
    char selections[5][20];  // User inputs for selections
    int numSelections, totalBill = 0;
    
    printf("Enter the number of selections (up to 5): ");
    scanf("%d", &numSelections);
    // 清空scanf留下的换行符
    getchar();

    for (int i = 0; i < numSelections; i++) {
        printf("Enter selection %d: ", i + 1);
        // 读取所有字符直到换行符,最多19个字符
        scanf("%19[^\n]", selections[i]);
        // 清空本次输入后的换行符
        getchar();

        int index = findItemIndex(selections[i]);
        if (index != -1) {
            printf("Price for %s: Rs%d/-
", selections[i], prices[index]);
            totalBill += prices[index];
        } else {
            printf("Selection %s not found in the menu.
", selections[i]);
        }
    }

    if (totalBill == 0) {
        printf("No valid selections found.
");
    } else {
        printf("The total bill payable including GST is: Rs%d/-
", totalBill);
    }

    return 0;
}

额外注意事项

  • 使用fgets时,要确保缓冲区大小足够,避免溢出;同时必须处理换行符,否则字符串末尾的\n会导致匹配失败。
  • 使用%[^\n]时,每次读取后都要清空输入缓冲区的换行符,否则下一次读取会直接捕获空内容。
  • 两款代码的大小写匹配逻辑(strcasecmp或自定义caseInsensitiveCompare)本身没有问题,无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:18:18