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
因此,我可以输入所有字符串,但第一次提示输入字符串是在错误的地方。
This is for a homework assignment to sort some given strings. I'm prompting the user for the number of strings they'd like to sort with scanf
, allocating an array based on that number, and then getting the strings themselves with fgets
.
Everything works fine if the number of strings is hardcoded, but the addition of scanf
to let the user decide screws things up. Here's the code:
#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;
}
And here's what the console looks like:
Input the number of strings that you'd like to sort: 3 Input string: Input string: foo Input string: bar
It skips over the first iteration of the loop, resulting in an empty string at the beginning of the array. My question is, why does it do that, and how can I fix it?
Here's what the console looks with the format string "%d\n"
passed to scanf
:
Input the number of strings that you'd like to sort: 3 foo Input string: Input string: bar Input string: baz
So, I can input all of the strings, but the first prompt for a string is in the wrong place.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您必须告诉 scanf 通过将 \n 放入 scanf 中来破坏 \n:
如果没有它,scanf 将读取剩余的换行符 [从按下 Enter 按钮时开始] 作为循环中的第一行
You have to tell scanf to clobber the \n by putting \n in the scanf:
without it, scanf will read the residual newline character [from when the enter button was hit] as the first line in the loop
真正的答案(以我谦虚但非常正确的观点:P)不是使用
scanf
。使用fgets
读取第一行(即数字),然后使用sscanf
或strtoul
自行解析该字符串。这样,当有人没有以良好的格式输入数据时,您就能够处理错误,并且您不必解决scanf
缺乏强大的空白处理的问题。另外,永远不要使用
int
来存储大小,除非您希望有很多长度为 -4 的数组。该标准将无符号类型size_t
指定为足够大以存储对象大小和数组索引的无符号类型。使用任何其他类型都不能保证有效。The real answer (in my humble but ever-so-correct opinion :P) is not to use
scanf
. Usefgets
to read the first line (i.e. the number) and then parse that string yourself with, say,sscanf
orstrtoul
. That way you have the ability to handle errors when someone doesn't input the data in a nice format, and you don't have to hack aroundscanf
's lack of robust whitespace handling.Also, never used an
int
to store sizes unless you expect to have a lot of arrays with -4 length. The standard specifies the unsigned typesize_t
as an unsigned type that is large enough to store object sizes and array indices. Using any other type isn't guaranteed to work.