使用scanf并同时获取
我知道我在问基本问题。 我在使用scanf
时遇到问题并gets
C程序。 当我使用scanf
, gets
不执行。 示例如下:
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指出这一点)。