C语言动态分配内存读任意长字符串时switch case下首次循环被跳过问题
问题根因
你用scanf("%d", &nav)读取菜单选项的时候,只会读取输入的数字部分,用户输入数字后按下的换行符会残留在stdin输入缓冲区中。后续第一次调用getline的时候,会直接读取到这个残留的换行符,返回一个仅包含换行的空字符串,看起来就像第一次循环被跳过了。
解决方案
- 方案1:在
scanf读取完数字后,清空输入缓冲区残留的换行
改起来成本最低,直接在scanf调用后新增一行代码吃掉残留字符即可:
scanf("%d",&nav); // 清空输入缓冲区直到读完换行符 while(getchar() != '\n');
- 方案2:统一用
getline读取所有输入,再解析内容
避免混用scanf和getline两类输入读取函数,从根源上避免缓冲区残留问题。读取菜单选项时也用getline读入整行,再用sscanf从字符串中解析数字:
char *line = NULL; size_t len = 0; getline(&line, &len, stdin); sscanf(line, "%d", &nav); free(line);
现有代码优化建议
dinput函数不需要手动提前分配内存,getline如果检测到传入的指针为NULL或者分配空间不足,会自动调用realloc扩容,直接初始化line = NULL、m = 0即可,还能避免手动分配空间大小不合适的问题:
char* dinput(void){ size_t m = 0; char *line = NULL; getline(&line, &m, stdin); return line; }
- 新增边界判断:
fopen、getline都有可能调用失败,建议增加返回值判断处理异常情况,避免空指针访问崩溃。 - 你当前
menu函数中的while条件存在语法错误,漏了括号,正确写法是while(nav!=0)。
内容的提问来源于stack exchange,提问作者Beatz_By Dre
相关产品推荐
相关产品推荐

