C语言重扫描字符串输入时如何避免while无限循环问题
问题描述
这段代码设计用于接收两个以逗号分隔的字符串,但运行时存在固定故障:第一次输入类似"Jill, Allen"的内容后,程序会重复复用该输入无限循环直到报错。
- 变量
fullInpt初始为数组类型,我曾尝试将其修改为const类型、手动赋值为"q"做测试,尝试让程序终止运行 - 打印
fullInpt的代码为测试用途,用来检查输入或手动修改变量后,变量实际存储的内容 - 我最初在zybooks平台运行这段代码,之后也在Code::blocks IDE中测试,确认两个环境下故障复现一致
程序需要覆盖的输入场景包括:
Jill , AllenJill,AllenJill Allen
字符串解析环节没有问题,核心故障出在读取新输入的扫描逻辑上。我刚开始学习C语言,欢迎任何形式的建议,提前致谢!
存在问题的原始代码
#include <stdio.h> #include <string.h> #include <stdbool.h> int main(void) { const int USER_TEXT_LIMIT = 100; char fullInpt[USER_TEXT_LIMIT]; char str1[20]; char str2[20]; bool inputDone; while(!inputDone) { printf("Enter input string:\n"); fgets(fullInpt, USER_TEXT_LIMIT, stdin); printf("%s", fullInpt); if(strcmp(fullInpt, "q") == 0) { inputDone = true; } else if(strchr(fullInpt, ',') == NULL) { printf("Error: No comma in string.\n"); printf("\n"); } else { sscanf(fullInpt, "%20[^,] , %20s", str1, str2); printf("First word: %s\n", str1); printf("Second word: %s\n", str2); printf("\n"); } } return 0; }
故障原因与修复方案
代码共有3个直接导致异常的问题:
- 局部布尔变量未初始化:
inputDone是栈上局部变量,赋值前存储的是随机垃圾值,第一次判断while(!inputDone)的结果完全不可控,大概率直接进入异常逻辑。 - 未处理
fgets读取的换行符:fgets会把用户输入回车产生的\n也存入缓冲区,输入q回车后,fullInpt实际存储的是"q\n",和"q"做strcmp比对永远不相等,退出逻辑永远无法触发。 sscanf格式串匹配规则错误:原格式串"%20[^,] , %20s"要求第一个字符串结束后必须先出现一个空格、再出现逗号,遇到Jill,Allen这类逗号前后无空格的输入会直接匹配失败,str1/str2残留旧值,输入缓冲区的内容也无法被正常消费,最终触发无限循环。另外长度设置为20会造成数组溢出——长度为20的char数组最多存储19个有效字符,必须给字符串结束符\0预留位置。
修复后的可运行代码:
#include <stdio.h> #include <string.h> #include <stdbool.h> int main(void) { const int USER_TEXT_LIMIT = 100; char fullInpt[USER_TEXT_LIMIT]; char str1[20]; char str2[20]; // 初始化退出标记 bool inputDone = false; while(!inputDone) { printf("Enter input string:\n"); fgets(fullInpt, USER_TEXT_LIMIT, stdin); // 剔除fgets读入的末尾换行符 fullInpt[strcspn(fullInpt, "\n")] = '\0'; printf("%s\n", fullInpt); if(strcmp(fullInpt, "q") == 0) { inputDone = true; } else if(strchr(fullInpt, ',') == NULL) { printf("Error: No comma in string.\n\n"); } else { // 修正格式串:兼容逗号前后任意数量空格、无空格的场景,修正读取长度避免溢出 sscanf(fullInpt, "%19[^,], %19s", str1, str2); // 清除第一个字符串末尾可能残留的空格 str1[strcspn(str1, " ")] = '\0'; printf("First word: %s\n", str1); printf("Second word: %s\n", str2); printf("\n"); } } return 0; }
内容的提问来源于stack exchange,提问作者turi_hdez
相关产品推荐
相关产品推荐

