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
相关产品推荐
相关产品推荐

