2

这是代码的编写方式。

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

4 回答 4

1

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

增加长度参数以匹配数组大小:

fgets(stringNum, 4, stdin);

或更好:

fgets(stringNum, sizeof stringNum, stdin);

您可能希望对enteredName.

fgets(3)手册页

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

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

于 2013-06-21T05:10:15.007 回答
1

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

编辑:有一篇非常有用的帖子提供了有关的信息fflush()。正如所描述的那样,fflush 基本上是为了被调用到输出流。虽然一些编译器提供了对刷新的支持stdin,但这被认为是一种未定义的行为。再看看程序,我发现使用sizeof可以创造奇迹并且是有效的,所以,我已经修改了程序以获得更好的效果。的使用sizeof也在此处的答案之一中进行了描述。

#include<stdio.h>
#include<stdlib.h>
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;
}
于 2013-06-21T06:42:27.303 回答
0

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

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

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

于 2013-06-21T05:13:42.777 回答
0

你试试下面这段代码:

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

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

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')
}
于 2013-06-21T07:42:15.310 回答