以下是代码的编写方式。
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数组中输入新名称,它只是进入下一个提示符(年龄)。除非此问题涉及链接列表,否则问题似乎与其他问题有关。你能帮我找到错误吗?谢谢!
答案 0 :(得分:1)
如果您输入两位数的年龄,则您的第二个fgets
来电会留下等待stdin
字符的字符(特别是换行符)。
增加length参数以匹配数组大小:
fgets(stringNum, 4, stdin);
或更好:
fgets(stringNum, sizeof stringNum, stdin);
您可能希望对enteredName
执行相同操作。
fgets()
函数最多只读取一个字符数 由给定流中的size
指定并将其存储在字符串中 的str
强>
您不需要为空终结者保留额外的数组条目,就像您正在做的那样 - fgets
将自行正确处理。
答案 1 :(得分:1)
问题是,你没有刷新输入缓冲区,这就是fgets()
直接带你去询问年龄的第二个提示的原因。这是遇到的常见问题,只需在{{1}之后添加fflush(stdin);//my compiler supports it
这段代码对我有用,希望它也适合你:
编辑:有一个非常useful post 提供有关fgets();
的信息。正如所描述的那样,fflush基本上是指调用输出流。虽然有些编译器提供了对刷新的支持{{1这被认为是一个未定义的行为。再看一下该程序,我发现使用fflush()
可以创造奇迹并且是有效的,所以,我已经修改了程序以获得更好的效果。 stdin
的使用也在其中一个答案中描述。
sizeof
答案 2 :(得分:0)
问题在于您不知道已读取的字符串是否包含newline
。如果它不包含newline
,则下一次调用fgets
将会读取此内容,并在其中留下一个空字符串。要防止它,请检查该行末尾是否包含newline
个字符。如果不是仅使用getchar()
和Voila !!阅读它(请注意,此解决方案仅对您的问题有效,而不是一般)。在阅读stringNum
字符串后添加此代码。
if(stringNum[strlen(stringNum)-1]!='\n')
{
getchar();
}
发生这种情况是因为,如果年龄是两位数,那么fgets
将会读到最后一位数而不是newline
字符。因此,如果最后一个字符不是\n
,您需要阅读它。如果年龄是一位数,则原始程序可以正常工作。
答案 3 :(得分:0)
您可以尝试以下代码:
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')
}