使用scanf并同时获取

我知道我在问基本问题。 我在使用scanf时遇到问题并gets C程序。 当我使用scanfgets不执行。 示例如下:

 void fun() { char str[10]; printf("Enter the string"); gets(str); printf("Entered string is %s\n", str); } int main() { int val; printf("Enter the value\n"); scanf("%d", &val); fun(); } 

如果我运行此程序,则gets不执行。 输入值后。 它不是在等待输入字符串。 输出是Enter the stringEntered string is 。 但是如果注释scanf ,它确实等待获取输入并正常工作。 谁能告诉我,我错了什么。

那么,这里的“正确”答案很简单:永远不要使用gets 。 就这么简单。 它甚至已从C11标准中删除。

原因是,您无法限制输入量,因此无论您保留多大的缓冲区,用户仍然可以生成足够的输入以导致缓冲区溢出。

你应该使用fgets ,如果你正在编写标准C.你应该使用getline如果你使用gcc (如Window下的MinGW或Cygwin),或任何支持最近POSIX标准的现代类Unix操作系统。


然后到实际问题,忽略gets问题。 问题是, scanf将包括输入按下的其余行留在输入流中。 一个强大的解决方案是编写一个函数,它将读取输入直到下一个换行符,类似于这个未经测试的函数:

 // this function reads given file until newline or end of file or error, // and returns last value read int eatLine(FILE *fp) { for(;;) { int ch = getc(fp); if (ch == '\n' || ch < 0) return ch; } } 

用法:

 if (scanf("%d", &myint) != 1) exit(0); // exit on invalid input if (eatLine(stdin) < 0) exit(0); // read and ignore rest of the line, exit on eof 

还有其他解决方案,例如读取缓冲线并在其上使用sscanf ,上面只是一个简单的可能性。

尝试用scanf("%d", &val) scanf("%d%*c", &val)替换scanf("%d", &val) scanf("%d%*c", &val)

手册页说明%c

通常跳过前导空格被抑制。

因此, %c匹配值后的换行符并将缓冲区留空。

这样,当你来到fun()例程时,等待输入。

* in %*c表示您不需要将字符存储在变量中(感谢@CoolGuy指出这一点)。