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
读取第一行(即数字),然后用sscanf
或strtoul
自己解析该字符串。 这样,当有人不以漂亮的格式输入数据时,您就能够处理错误,并且您不必破解scanf
缺乏强大的空白处理能力。
此外,从未使用过int
来存储大小,除非你期望有很多长度为-4的数组。 该标准将无符号类型size_t
指定为无符号类型,该类型足以存储对象大小和数组索引。 使用任何其他类型不保证可以工作。
你必须通过将\ n放在scanf中告诉scanf来破坏\ n:
scanf("%d\n", &numStrings)
没有它,scanf将读取剩余换行符[从输入按钮被击中时]作为循环中的第一行