get()如何在scanf之后工作?
这个问题在这里已经有了答案:
scanf("%d", &num);
"%d"
后没有空格,读取一个数字后停止扫描。 因此,对于输入123Enter, 'n'
保留在stdin
以用于下一个输入函数,如现在的非标准gets()
。 gets()
读取单个'n'
并返回。 通过添加一个空格, scanf("%d ", &num);
消耗数字后面的空格,直到在数字后面输入非白色花样才返回。
通过添加一个空格, scanf("%d ", &num);
直到数字后面输入非空格才会返回(如下面的'a'
)。 由于stdin
通常是行缓冲的,这意味着需要首先输入2行。 123输入abcEnter。
建议使用fgets()
来读取用户输入的一行。
char str[10*2]; // no need for such a small buffer
int num;
printf("Enter your number : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
sscanf(str, "%d", &num);
printf("%dn",num);
printf("Enter data : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
fputs(str, stdout);
更健壮的代码将检查fgets(), sscanf()
并使用strtol()
而不是sscanf()
。
C FAQ涵盖了scanf
所有这些问题。 看看为什么大家都说不要使用scanf? 我应该用什么来代替? 和相关条目。 一般来说,您将使用fgets
然后处理结果行,例如使用sscanf
并检查sscanf
成功。 这样可以避免留下未分类的输入并冒着无限循环的风险。
int number;
char line[255];
fgets( line, sizeof(line), stdin );
if( sscanf( line, "%d", &number ) != 1 ) {
fputs("That doesn't look like a number.n", stdin);
}
请注意, fgets
将读取换行符或缓冲区可容纳的数量。 如果该行比缓冲区大,则可能只能读取部分行。 接下来从输入读取将获得该行的其余部分。 有办法避免这种情况,比如POSIX getline函数,但至少你不会在无限循环中结束。
让我们破译一些评论。
永远不要使用gets
。 使用fgets
。
你不使用gets
的原因是因为没有办法限制从stdin
读取多少内容。 这意味着用户可以溢出导致严重破坏的缓冲区。
char buffer[32];
// What the line is more than 31 characters?
gets(buffer);
fgets()
取得缓冲区的大小,最多可以读取多个字符。 这可以防止缓冲区溢出。
char buffer[32];
// If there's more than 31 characters it will stop reading.
// The next read of stdin will get the rest of the line.
fgets( buffer, sizeof(buffer), stdin );
“C中没有gets()
函数。”
是的,C中有一个gets()
函数。
是的,C中没有gets()
函数。
这取决于你在谈论哪个C.
有些人说“C”是指当前的C11标准。 其他人在说“C”时意味着C99是以前的标准。 有些仍然坚持原标准C90。 C90中有一个gets()
函数。 它在C99中被弃用。 它从C11中的语言中删除。
C编译器和文档落后于标准的程度非常非常非常落后。 许多人仍在全力支持C99。 如果你工作到C11,你会因缺乏支持而感到惊讶。 如果你想要你的代码在大多数编译器上工作,写入C99。
无论如何,不要使用gets
。