为什么 scanf 将值传递给我的函数,不希望 scanf 将值发送给被调用者
Why does scanf pass the value to my function, dont want scanf to send value to callee
我知道 scanf()
用法,不鼓励使用。但我遇到了问题,scanf 将标准输入值发送到下一个函数标准输入。我想知道为什么会这样。
代码:
#include <stdio.h>
void ffgets() {
char name[40];
printf("What's your name? ");
if (fgets(name, 40, stdin)) {
printf("Hello %s", name);
}
}
int main(int argc, char **argv) {
int a;
printf("enter a number: ");
int res = scanf("%d", &a);
if (res > 0) {
printf("Valid Integer %d.\n", a);
} else {
printf("It's not a number\n");
}
ffgets();
return 0;
}
输出:
测试用例 1:
为什么函数不请求标准输入,它只打印空字符串
./a.out
enter a number: 23
Valid Integer 23.
What's your name? Hello
测试用例 2:我输入了带有传递给 name 的特殊字符的字符串。
./a.out
enter a number: random##¤
It's not a number
What's your name? Hello random##¤
我不想将 main 中的标准输入值传递给函数,该怎么做?
原因是在第一种情况下,匹配输入被 scanf()
消耗,但换行符 \n
出现在输入缓冲区中。在第一种情况下, 和 是 fgets()
的有效输入终止符。
相关,引用 C11
,章节 §7.21.6.2
Trailing white space (including new-line characters) is left unread unless matched by a
directive. [....]
在第二种情况下,匹配失败发生,这使得整个输入在 fgets()
调用时在输入缓冲区中可用,因此 fgets()
读取整个内容。
如果您输入的内容 scanf
与格式规范不匹配,那么它会立即停止并且 将输入留在输入缓冲区中以供下一个输入函数使用.
此外,当使用 scanf
时,它不会消耗输入缓冲区中的尾随换行符,并将其留给下一个输入函数。
要解决这两个问题,请考虑使用 fgets
从输入中获取整行,然后使用 sscanf
解析字符串。
I am aware of scanf() usage and is not encouraged.
这正是来自 scanf()
的问题(即,scanf
未使用的输入留在输入缓冲区中,这与用户的预期相反)。因此,正如您似乎已经知道的那样,解决方案是不使用该功能。
创建一个函数来读取完整的输入行,并使用 sscanf()
或 strtol
或朋友从那里解析一个 int 并不难:
#include <stdio.h>
#include <limits.h>
int getint(void)
{
char buffer[120] = {0}; /* arbitrary limit */
fgets(buffer, 120, stdin);
int a;
if (sscanf(buffer, "%d", &a) == 1) {
return a;
}
return INT_MIN;
}
(当然 INT_MIN
是一个有效的输入数字,因此您可能希望有一些更好的方法来返回错误。也许考虑如何处理数字后面的垃圾。)
我知道 scanf()
用法,不鼓励使用。但我遇到了问题,scanf 将标准输入值发送到下一个函数标准输入。我想知道为什么会这样。
代码:
#include <stdio.h>
void ffgets() {
char name[40];
printf("What's your name? ");
if (fgets(name, 40, stdin)) {
printf("Hello %s", name);
}
}
int main(int argc, char **argv) {
int a;
printf("enter a number: ");
int res = scanf("%d", &a);
if (res > 0) {
printf("Valid Integer %d.\n", a);
} else {
printf("It's not a number\n");
}
ffgets();
return 0;
}
输出:
测试用例 1:
为什么函数不请求标准输入,它只打印空字符串
./a.out
enter a number: 23
Valid Integer 23.
What's your name? Hello
测试用例 2:我输入了带有传递给 name 的特殊字符的字符串。
./a.out
enter a number: random##¤
It's not a number
What's your name? Hello random##¤
我不想将 main 中的标准输入值传递给函数,该怎么做?
原因是在第一种情况下,匹配输入被 scanf()
消耗,但换行符 \n
出现在输入缓冲区中。在第一种情况下, 和 是 fgets()
的有效输入终止符。
相关,引用 C11
,章节 §7.21.6.2
Trailing white space (including new-line characters) is left unread unless matched by a directive. [....]
在第二种情况下,匹配失败发生,这使得整个输入在 fgets()
调用时在输入缓冲区中可用,因此 fgets()
读取整个内容。
如果您输入的内容 scanf
与格式规范不匹配,那么它会立即停止并且 将输入留在输入缓冲区中以供下一个输入函数使用.
此外,当使用 scanf
时,它不会消耗输入缓冲区中的尾随换行符,并将其留给下一个输入函数。
要解决这两个问题,请考虑使用 fgets
从输入中获取整行,然后使用 sscanf
解析字符串。
I am aware of scanf() usage and is not encouraged.
这正是来自 scanf()
的问题(即,scanf
未使用的输入留在输入缓冲区中,这与用户的预期相反)。因此,正如您似乎已经知道的那样,解决方案是不使用该功能。
创建一个函数来读取完整的输入行,并使用 sscanf()
或 strtol
或朋友从那里解析一个 int 并不难:
#include <stdio.h>
#include <limits.h>
int getint(void)
{
char buffer[120] = {0}; /* arbitrary limit */
fgets(buffer, 120, stdin);
int a;
if (sscanf(buffer, "%d", &a) == 1) {
return a;
}
return INT_MIN;
}
(当然 INT_MIN
是一个有效的输入数字,因此您可能希望有一些更好的方法来返回错误。也许考虑如何处理数字后面的垃圾。)