scanf和fgets有问题

时间:2011-02-08 03:44:49

标签: c stdin scanf fgets

这是为家庭作业分配一些给定的字符串。我正在提示用户输入他们想要使用scanf排序的字符串数,根据该数字分配数组,然后使用fgets获取字符串。

如果字符串的数量是硬编码的,那么一切正常,但添加scanf以让用户决定搞砸了。这是代码:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#define LENGTH  20 // Maximum string length.

int main(void)
{
    int index, numStrings = 0;
    char **stringArray;
    printf("Input the number of strings that you'd like to sort: ");
    assert(scanf("%d", &numStrings) == 1);
    stringArray = (char **)malloc(numStrings * sizeof(char *));

    for (index = 0; index < numStrings; index++)
    {
        stringArray[index] = (char *)malloc(LENGTH * sizeof(char));
        assert(stringArray[index] != NULL);
        printf("Input string: ");
        assert(fgets(stringArray[index], LENGTH, stdin) != NULL);
    }

    // Sort strings, free allocated memory.

    return 0;
}

以下是控制台的样子:

Input the number of strings that you'd like to sort: 3
Input string: Input string: foo
Input string: bar

它会跳过循环的第一次迭代,从而在数组的开头产生一个空字符串。我的问题是,为什么会这样做,我该如何解决?


以下是控制台看到的格式字符串"%d\n"传递给scanf的内容:

Input the number of strings that you'd like to sort: 3
foo
Input string: Input string: bar
Input string: baz

所以,我可以输入所有字符串,但字符串的第一个提示是在错误的位置。

2 个答案:

答案 0 :(得分:6)

你必须告诉scanf将\ n放在scanf:

中来破坏\ n
scanf("%d\n", &numStrings)

没有它,scanf将读取剩余换行符[从输入按钮被击中时]作为循环中的第一行

答案 1 :(得分:3)

真正的答案(以我的谦虚但非常正确的观点:P)不是使用scanf。使用fgets读取第一行(即数字),然后使用sscanfstrtoul自行解析该字符串。这样,当有人不以漂亮的格式输入数据时,您就能够处理错误,并且您不必破解scanf缺乏强大的空白处理。

此外,从未使用int来存储大小,除非您希望有很多长度为-4的数组。该标准将无符号类型size_t指定为无符号类型,该类型足以存储对象大小和数组索引。使用任何其他类型都不能保证有效。