c - gets() 在 scanf 之后如何工作?
c - how gets() work after scanf?
我有两个问题:
- 为什么只有当我在“%d”中执行 space 时 -->
scanf("%d ", &num);
它才有效?
我在 scnaf 和 gets 之间尝试了 fflush(stdin) \ _flushall()
但它不起作用,它跳过了 gets。
- 当我执行 space 时,它首先执行 scanf,然后执行 gets,然后打印数字和字符串。
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");
}
- why only when i do space in "%d " --> scanf("%d ", &num); it works?
scanf("%d", &num);
在 "%d"
之后没有 space,在读取数字后停止扫描。所以输入 123Enter, '\n'
保留在 stdin
中用于下一个输入函数,例如现在的非标准 gets()
。 gets()
读取单个 '\n'
和 return。通过添加 space,scanf("%d ", &num);
会在数字后消耗白色-space 并且不会 return 直到在数字后输入非白色-scape。
- When I do the space, it first does scanf then the gets and after that it print the number and print the string.
通过添加一个space,scanf("%d ", &num);
不会return,直到在数字后输入非白色-space(如'a'
下列)。由于 stdin
通常是行缓冲的,这意味着需要先输入 2 行。 123输入 a bc输入.
建议改为使用 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("%d\n",num);
printf("Enter data : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
fputs(str, stdout);
更健壮的代码会检查 fgets(), sscanf()
的结果并使用 strtol()
而不是 sscanf()
。
C 常见问题解答涵盖了 scanf
中的所有这些问题。请参阅 Why does everyone say not to use scanf? What should I use instead? 和相关条目。通常,您将使用 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
将读取到换行符 或您的缓冲区可以容纳的最大容量 。如果该行大于您的缓冲区,它可能只读取该行的一部分。接下来从输入中读取将获得该行的其余部分。有一些方法可以避免这种情况,例如 the POSIX getline function,但至少您不会陷入无限循环。
让我们解读一些评论。
永远不要使用 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()
函数
是的,没有 gets()
C 中的函数。
这取决于你说的是哪个 C。
有些人说 "C" 是指 C11,即当前标准。其他人说 "C" 表示 C99 是以前的标准。有些仍然坚持原始标准 C90。 C90中有一个gets()
函数。它在 C99 中被弃用。它已从 C11 中的语言中删除。
C 编译器和文档远远落后于标准。许多人仍在致力于全面支持 C99。如果你工作到 C11,你会对缺乏支持感到非常惊讶。如果您希望您的代码适用于大多数编译器,请写入 C99。
总之,不要使用gets
。
我有两个问题:
- 为什么只有当我在“%d”中执行 space 时 -->
scanf("%d ", &num);
它才有效?
我在 scnaf 和 gets 之间尝试了 fflush(stdin) \ _flushall()
但它不起作用,它跳过了 gets。
- 当我执行 space 时,它首先执行 scanf,然后执行 gets,然后打印数字和字符串。
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"); }
- why only when i do space in "%d " --> scanf("%d ", &num); it works?
scanf("%d", &num);
在 "%d"
之后没有 space,在读取数字后停止扫描。所以输入 123Enter, '\n'
保留在 stdin
中用于下一个输入函数,例如现在的非标准 gets()
。 gets()
读取单个 '\n'
和 return。通过添加 space,scanf("%d ", &num);
会在数字后消耗白色-space 并且不会 return 直到在数字后输入非白色-scape。
- When I do the space, it first does scanf then the gets and after that it print the number and print the string.
通过添加一个space,scanf("%d ", &num);
不会return,直到在数字后输入非白色-space(如'a'
下列)。由于 stdin
通常是行缓冲的,这意味着需要先输入 2 行。 123输入 a bc输入.
建议改为使用 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("%d\n",num);
printf("Enter data : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
fputs(str, stdout);
更健壮的代码会检查 fgets(), sscanf()
的结果并使用 strtol()
而不是 sscanf()
。
C 常见问题解答涵盖了 scanf
中的所有这些问题。请参阅 Why does everyone say not to use scanf? What should I use instead? 和相关条目。通常,您将使用 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
将读取到换行符 或您的缓冲区可以容纳的最大容量 。如果该行大于您的缓冲区,它可能只读取该行的一部分。接下来从输入中读取将获得该行的其余部分。有一些方法可以避免这种情况,例如 the POSIX getline function,但至少您不会陷入无限循环。
让我们解读一些评论。
永远不要使用 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()
函数
是的,没有 gets()
C 中的函数。
这取决于你说的是哪个 C。
有些人说 "C" 是指 C11,即当前标准。其他人说 "C" 表示 C99 是以前的标准。有些仍然坚持原始标准 C90。 C90中有一个gets()
函数。它在 C99 中被弃用。它已从 C11 中的语言中删除。
C 编译器和文档远远落后于标准。许多人仍在致力于全面支持 C99。如果你工作到 C11,你会对缺乏支持感到非常惊讶。如果您希望您的代码适用于大多数编译器,请写入 C99。
总之,不要使用gets
。