3

这是用于对一些给定字符串进行排序的家庭作业。我提示用户输入他们想要排序的字符串的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;
}

这是控制台的样子:

输入要排序的字符串数:3
输入字符串:输入字符串:foo
输入字符串:bar

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


"%d\n"以下是传递给格式字符串的控制台的外观scanf

输入要排序的字符串数:3
富
输入字符串:输入字符串:bar
输入字符串:baz

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

4

2 回答 2

6

您必须通过将 \n 放入 scanf 来告诉 scanf 破坏 \n:

scanf("%d\n", &numStrings)

没有它,scanf 将读取剩余的换行符 [从按下回车按钮时] 作为循环中的第一行

于 2011-02-08T03:52:44.163 回答
3

真正的答案(以我谦虚但非常正确的观点:P)是不要使用scanf. 用于fgets读取第一行(即数字),然后自己解析该字符串,例如,sscanfstrtoul。这样,当有人没有以良好的格式输入数据时,您就有能力处理错误,并且您不必解决scanf' 缺乏健壮的空白处理。

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

于 2011-02-08T05:09:21.457 回答