scanf和fgets有问题

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

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

 #include  #include  #include  #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
 FOO
输入字符串:输入字符串:bar
输入字符串:baz

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

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

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

你必须通过将\ n放在scanf中告诉scanf来破坏\ n:

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

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