fgets()不会再次提示用户

这是代码的编写方式。

int main() { char enteredName[30]; char stringNum[4]; char continueLetter = 0; int continueProgram = 0; int enteredAge; int i; do { memset(enteredName,'\0', 30); printf("Please enter a name: "); fgets(enteredName, 29, stdin); printf("\n\nNow please enter your age: "); fgets(stringNum, 3, stdin ); for(i = 0; i < 30; i++) { if (enteredName[i] == '\n') { enteredName[i] = '\0'; break; } } for(i = 0; i < 4; i++) { if (stringNum[i] == '\n') { stringNum[i] = '\0'; break; } } enteredAge = atol(stringNum); } while(); 

当我第二次运行循环时,我无法在char数组中输入新名称,它只是进入下一个提示符(年龄)。 除非此问题涉及链接列表,否则问题似乎与其他问题有关。 你能帮我找到错误吗? 谢谢!

如果输入两位数字的年龄,你的第二个fgets调用会留下等待从stdin读取的字符(特别是换行符)。

增加length参数以匹配数组大小:

 fgets(stringNum, 4, stdin); 

或更好:

 fgets(stringNum, sizeof stringNum, stdin); 

您可能希望对enteredName执行相同的enteredName

fgets(3)手册页 :

fgets()函数最多读取一个小于给定流中size指定的字符数,并将它们存储在字符串str

您不需要为空终止符保留额外的数组条目,就像您正在做的那样 – fgets将自己正确处理它。

问题是,你没有刷新输入缓冲区,这就是为什么fgets()直接带你去询问age的第二个提示。这是遇到的常见问题,只需添加fflush(stdin);//my compiler supports itfgets();之后fflush(stdin);//my compiler supports it fgets(); 这是对我有用的代码,希望它也适合你:

编辑:有一个非常有用的post提供有关fflush() 。正如描述fflush基本上是要调用输出流。尽管一些编译器提供了对刷新stdin支持,但这被认为是一种未定义的行为。虽然有再看看这个程序,我发现使用sizeof可以创造奇迹而且是有效的,所以,我已经修改了程序以求更好。 sizeof的使用也在这里的答案之一中描述。

 #include #include int main() { char enteredName[30]; char stringNum[4]; int continueProgram=0; int i; while(continueProgram<3) { setbuf(stdout,NULL); printf("Please enter a name: "); fgets(enteredName, sizeof enteredName, stdin); printf("\n\nNow please enter your age: "); fgets(stringNum,sizeof stringNum, stdin ); for(i = 0; i < 30; i++) { if (enteredName[i] == '\n') { enteredName[i] = '\0'; break; } } for(i = 0; i < 4; i++) { if (stringNum[i] == '\n') { stringNum[i] = '\0'; break; } } //enteredAge = atol(stringNum); continueProgram++; } return 0; } 

问题是您不知道已读取的字符串是否包含newline 。 如果它不包含newline ,那么下次调用fgets将会读取它,并在其中留下一个空字符串。 要防止它,请检查该行是否在末尾包含newline 。 如果不是只使用getchar()和Voila !!读取它(请注意,此解决方案仅对您的问题有效,而不是一般)。 在读取stringNum字符串后添加此代码。

 if(stringNum[strlen(stringNum)-1]!='\n') { getchar(); } 

发生这种情况是因为,如果年龄是两位数,那么fgets将会读到最后一位数而不是newline 。 因此,如果最后一个字符不是\n ,您需要阅读它。 如果年龄是一位数,原始程序工作正常。

你试试下面这段代码:

 if(stringNum[strlen(arr)-1]=='\n') stringNum[strlen(arr)-1]='\0'; else while(getchar()!='\n'); 

每当您输入两位数的年龄时,按Enter键时插入的换行符将存储在缓冲区中。 上面这段代码的作用是,它将检查存储的最后一个字符是否填充了换行符,如果是,则它将用null终止符替换它。 否则,除非从缓冲区中删除换行符,否则它将继续从缓冲区读取。

PS:如果你正在使用borland那么你将有fflush(stdin)从PHlFounder指示的冲洗缓冲区中删除任何额外的字符,但是如果你碰巧使用gcc那么这个方法非常好。

您也可以为这段代码创建一个函数或宏,并在每次需要时调用它,例如。

 void function(char * arr) { if(arr[strlen(arr)-1]=='\n') arr[strlen(arr)-1]='\0'; else while(getchar()!='\n') }