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
。
scanf("%d ", &num);
才会返回。 - chux - Reinstate Monicascanf
交互,因为你绝对不应该使用它。 - William Pursellfflush(stdin)
。 - Ed Healgets()
函数。main
函数必须返回int
类型。 - n. m.