fgets()不会再次提示用户

时间:2013-06-21 05:02:42

标签: c

以下是代码的编写方式。

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数组中输入新名称,它只是进入下一个提示符(年龄)。除非此问题涉及链接列表,否则问题似乎与其他问题有关。你能帮我找到错误吗?谢谢!

4 个答案:

答案 0 :(得分:1)

如果您输入两位数的年龄,则您的第二个fgets来电会留下等待stdin字符的字符(特别是换行符)。

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

fgets(stringNum, 4, stdin);

或更好:

fgets(stringNum, sizeof stringNum, stdin);

您可能希望对enteredName执行相同操作。

来自fgets(3) man page

  

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')
}