如何在C语言运行时设置fgets()读取长度?求助排查问题
为什么用scanf输入长度后fgets会被跳过?
问题出在scanf("%d", &i)的输入处理逻辑上:当你输入数字并按下回车时,scanf只会读取输入中的数字部分,而回车产生的换行符\n会残留在标准输入缓冲区里。
当后续调用fgets(str, i, stdin)时,fgets会从缓冲区里读取字符,它一遇到这个残留的换行符就会停止读取(因为fgets以换行符作为行结束标志),直接返回空行,看起来就像被“跳过”了,实际上它已经完成了读取操作。
而硬编码版本能正常运行,是因为程序启动后输入缓冲区是空的,fgets会等待用户输入,不会被残留的换行符干扰。
解决方法
方法一:手动清空缓冲区残留的换行符
在scanf之后调用getchar(),读取并丢弃缓冲区里的换行符:#include <stdlib.h> #include <stdio.h> int main() { int i; char str[100]; puts("Enter a number: "); scanf("%d", &i); getchar(); // 吃掉残留的换行符 fgets(str, i, stdin); printf("String contents: %s", str); return 0; }注意:如果用户输入数字后还输入了其他非数字字符(比如
123abc\n),getchar()只能处理一个字符,这种情况可以用循环清空整个缓冲区:while ((getchar()) != '\n');方法二:用fgets读取数字输入,再转换为整数
这种方法可以彻底避免缓冲区残留问题,同时还能处理更复杂的输入情况:#include <stdlib.h> #include <stdio.h> #include <string.h> int main() { int i; char num_str[20]; char str[100]; puts("Enter a number: "); fgets(num_str, sizeof(num_str), stdin); // 去掉num_str里的换行符(如果存在) num_str[strcspn(num_str, "\n")] = '\0'; i = atoi(num_str); // 或者用strtol做更安全的转换 // 确保i不超过数组长度,避免缓冲区溢出 if (i > 100) { i = 100; } fgets(str, i, stdin); printf("String contents: %s", str); return 0; }推荐使用
strtol代替atoi,因为它能检测转换错误,比如输入非数字字符的情况。
额外提醒
无论用哪种方法,都要确保输入的i不超过数组str的长度(这里是100),否则会导致缓冲区溢出,引发未定义行为。
内容的提问来源于stack exchange,提问作者henryalligator
相关产品推荐
相关产品推荐

