这个问题在这里已有答案:
我有两个问题:
- 为什么只有当我在"%d " - >
scanf("%d ", &num);
做空间时才有效?
我在scnaf和gets之间尝试了 fflush(stdin) \ _flushall()
并且它不起作用,它跳过了获取 .
- 当我做空间时,它首先执行scanf然后执行获取,然后打印数字并打印字符串 .
void main()
{
char ch, str[10];
int num;
printf("Enter your number : ");
scanf("%d ", &num);
printf("%d\n",num);
gets(str);
puts(str);
system("pause");
}
2 回答
scanf("%d", &num);
"%d"
后没有空格,读取数字后停止扫描 . 因此,对于输入123Enter,'\n'
保留在stdin
中,用于下一个输入函数,如现在的非标准gets()
.gets()
读取单个'\n'
并返回 . 通过添加空格,scanf("%d ", &num);
会在数字后面消耗空格,并且在数字后面输入非白色空格后才会返回 .通过添加空格,
scanf("%d ", &num);
不会返回,直到在数字后面输入非空格(如下面的'a'
中所示) . 由于stdin
通常是行缓冲的,这意味着需要首先输入2行 . 123输入abcEnter .建议改为使用
fgets()
来读取一行用户输入 .更强大的代码将检查
fgets(), sscanf()
的结果并使用strtol()
而不是sscanf()
.C FAQ涵盖
scanf
的所有这些问题 . 请参阅Why does everyone say not to use scanf? What should I use instead?和相关条目 . 通常,您将使用fgets
,然后处理结果行,例如sscanf
并检查sscanf
是否成功 . 这样可以避免留下未解析的输入并冒无限循环的风险 .请注意,
fgets
将读取换行符或缓冲区可以容纳的内容 . 如果该行大于您的缓冲区,则它可能只读取该行的一部分 . 接下来从输入读取将获得该行的其余部分 . 有办法避免这种情况,例如the POSIX getline function,但至少你不会陷入无限循环 .让我们解读一些评论 .
不要使用获取 . 使用fgets .
你不使用
gets
的原因是因为没有办法限制从stdin
读取多少 . 这意味着用户可以溢出缓冲区,造成破坏 .fgets()
占用缓冲区的大小,最多会读取多个字符 . 这可以防止缓冲区溢出 .“C中没有gets()函数 . ”
是的,C中有一个
gets()
函数 .是的,C中没有
gets()
函数 .这取决于你在说什么C.
有些人说"C"意味着C11,目前的标准 . 其他人说"C"意味着C99以前的标准 . 有些人仍坚持原标准C90 . C90中有一个
gets()
功能 . 它在C99中已弃用 . 它已从C11中的语言中删除 .C编译器和文档落后于标准,非常非常远 . 许多人仍在全力支持C99 . 如果你为C11工作,你将会因缺乏支持而感到非常惊讶 . 如果您希望代码适用于大多数编译器,请写入C99 .
无论如何,不要使用
gets
.