C scanf不适用于多字输入

时间:2014-05-05 14:27:23

标签: c structure scanf

我有这段代码。

#include <stdio.h>
struct name
{
    int age;
    char fullname[20];
};

struct name names[20];

int main()
{
    int n,i;
    printf("Count of names:\n");
    scanf("%d",&n);
    for (i = 0; i < n; i++)
    {
        printf("Name %d : ",i);
        scanf("%[^\n]s",names[i].fullname);
    }
    return 0;
}

当我执行时:

rupam@linux ~ $ ./a.out 
Count of names:
5
Name 0 : Name 1 : Name 2 : Name 3 : Name 4 : 
rupam@linux ~ $

它不会等待用户输入。不知怎的,scanf无效。

好吧,如果我使用

scanf("%s",names[i].fullname);

适用于单字输入。 我在这做错了什么?

3 个答案:

答案 0 :(得分:2)

所以让我们看看这里输入会发生什么。首先,调用scanf("%d"来读取整数。假设您输入类似 5 Enter 的内容,scanf调用将读取数字并将其转换为整数。由于它找到至少一个数字,它将成功,读取该数字并从 Enter 中删除\n以进行读取。

现在进入循环,在其中调用scanf("%[^\n]s",尝试读取一个或多个非换行符后跟换行符,然后尝试读取s。由于下一个输入字符是换行符,因此会立即失败(不读取任何内容),但您不会检查scanf的返回值,因此您不会注意到。然后你循环尝试阅读更多,这将再次失败。

所以你需要做的就是忽略换行符。最简单的方法可能是只使用格式中的空格,这会导致scanf读取并忽略空格,直到找到非空白字符;将您的第二个scanf更改为:

scanf(" %19[^\n]", names[i].fullname);

请注意这里的一些其他更改。我们摆脱了虚假的s,因为您并不特别希望在名称后匹配s。我们还添加了19个字符的限制,以避免溢出fullname数组(最多19个字符+终止NULL字节为1)。

答案 1 :(得分:0)

在printf for for循环后使用getchar():

#include <stdio.h>
struct name
{
    int age;
    char fullname[20];
};

struct name names[20];

int main()
{
    int n,i;
    printf("Count of names:\n");
    scanf("%d",&n);
    for (i = 0; i < n; i++)
    {
        printf("Name %d : ",i);
        getchar();//getchar here
        scanf("%[^\n]s",names[i].fullname);
    }
    return 0;
}

答案 2 :(得分:0)

如果您可能使用未来Windows行结尾的文件(将文件重定向到标准输入),那么您可以使用<,而不是按照@jahan的建议使用一个getchar() / p>

if(getchar()=='\r') getchar();

这可以提高代码的可移植性。