为什么scanf需要额外的参数?
scanf takes extra parameter why?
我是 c++ 及其开发的新手,我曾经扫描以获取输入参数。但是我给了两个输入参数。但是程序允许我输入额外的参数。请解释为什么会这样。请在下面找到我使用的代码。
#include <iostream>
int main(int argc, const char * argv[]) {
int a,b;
scanf("%i %i ",&a,&b);
printf("a-> %i",a);
printf("b-> %i",b);
return 0;
}
输出(允许40作为额外参数)
20
30
40
a-> 20b-> 30Program ended with exit code: 0
您的格式在第二个 %i 之后有一个 space。 scanf
将读取额外数据以匹配 space。删除 space,它应该会按预期工作。
scanf takes extra parameter why?
这不是一个准确的结论。额外的输入留在输入流中。它没有被 scanf
消耗。它在程序结束时被丢弃。
如果你有另一个 scanf
行,
scanf("%d", &c);
值 40
将被读入 c
。
在与 Benjamin Lindley 的评论中讨论后,我想我最初可能误解了问题的意图。
也许问题不在于为什么允许输入第三个输入,而在于为什么需要输入scanf
满足之前的第三个输入。
在那种情况下,我认为@Dale Wilson 的回答基本上是正确的(尽管解释有点短)。
scanf
格式字符串中的 space 意味着 scanf 将跳过 所有 个连续的白色 space。按键盘上的回车键通常被解释为在输入流中输入一个换行符,这被认为是白色 space.
由于格式字符串中的尾部 space,他需要输入一些不是白色的字符space 得到 scanf
到 return,所以即使他不需要或不希望程序读取第三个参数,他也需要输入 一些东西 scanf can/will 识别为输入中 whitespace 的结尾,与格式字符串中的尾随 space 匹配。 "something" 是什么并不重要,除了它不能是 white-space (space, new-line, tab, vertical tab, 可能其他取决于语言环境)。
下面的文字是我最初的回答,但经过讨论和重读,我认为它没有抓住 OP 可能想问的重点,所以虽然它说的是真的,但我怀疑它有多大实际用处.
C 和 C++ 基本上都将标准输入视为一个文件。他们不能(也不会尝试)控制您输入标准输入的数据。他们所能做的就是在阅读数据后决定如何处理这些数据。
在这种情况下,您根本没有要求读取该数据,因此它被忽略了。
程序的标准输入有点像程序是一个人站在繁忙的街道上,周围有数百人。该程序可以听他们说什么或不听他们说什么——但实际上不能做任何事情来阻止他们所有人说话。同样,程序可以读取或不读取某些输入,但无法阻止您输入它不需要或不关心的额外输入。
你写的方式 scanf
是完全错误的,应该避免。
而不是你的scanf
:
scanf("%i %i ",&a,&b);
你应该使用这个:
scanf("%i%i", &a, &b);
避免在 scanf
.
中使用空格或除 %datatype 之外的任何其他内容
您想要的工作代码:
#include <iostream>
using namespace std;
#include <stdio.h>
int main(int argc, const char *argv[]) {
int a, b;
scanf("%i%i", &a, &b);
printf("a-> %i", a);
printf("b-> %i", b);
return 0;
}
在 C 中,调用者和被调用者必须就在调用之前压入堆栈的参数数量达成一致。
scanf
也不例外,它采用可变数量的参数,基本上由提供的格式字符串决定。 scanf
扫描格式说明符并期望每个指定格式都有一个对应的变量地址。
在您编写的测试程序中
scanf("%i %i ",&a,&b);
表示从输入缓冲区stdin中取出两个整数,放在a和b的地址上。然而,没有什么可以阻止您在 stdin 中写入更多字符,这些可以通过随后调用 scanf 来读取。
对于键盘输入,通常应避免使用 scanf,而是使用 fgets(),它允许您指定输入的最大大小,然后使用 sscanf() 从缓冲区读取。
char buffer[128];
if (fgets(buffer,sizeof(buffer),stdin) != NULL)
{
if (sscanf( buffer, "%i %i", &a, &b) == 2)
{
printf( "the numbers are %i and %i\n", a,b );
}
}
请注意,您包含了 C++ header 但根本没有使用它,您可能想要删除该包含或完全更改代码并改用 cin/cout。
虽然 scanf 方便易用,但请注意它
- 不会为您检查输入参数(因此,您有责任检查用户的输入参数)
因此,当你做
scanf("%i %i ",&a,&b);
scanf 只会 'scan' 进行输入,直到它认为完成为止。
因此,您应该像这样检查输入
if (scanf("%i %i", &a, &b) != 2) {
/* throw error and exit */
}
我是 c++ 及其开发的新手,我曾经扫描以获取输入参数。但是我给了两个输入参数。但是程序允许我输入额外的参数。请解释为什么会这样。请在下面找到我使用的代码。
#include <iostream>
int main(int argc, const char * argv[]) {
int a,b;
scanf("%i %i ",&a,&b);
printf("a-> %i",a);
printf("b-> %i",b);
return 0;
}
输出(允许40作为额外参数)
20
30
40
a-> 20b-> 30Program ended with exit code: 0
您的格式在第二个 %i 之后有一个 space。 scanf
将读取额外数据以匹配 space。删除 space,它应该会按预期工作。
scanf takes extra parameter why?
这不是一个准确的结论。额外的输入留在输入流中。它没有被 scanf
消耗。它在程序结束时被丢弃。
如果你有另一个 scanf
行,
scanf("%d", &c);
值 40
将被读入 c
。
在与 Benjamin Lindley 的评论中讨论后,我想我最初可能误解了问题的意图。
也许问题不在于为什么允许输入第三个输入,而在于为什么需要输入scanf
满足之前的第三个输入。
在那种情况下,我认为@Dale Wilson 的回答基本上是正确的(尽管解释有点短)。
scanf
格式字符串中的 space 意味着 scanf 将跳过 所有 个连续的白色 space。按键盘上的回车键通常被解释为在输入流中输入一个换行符,这被认为是白色 space.
由于格式字符串中的尾部 space,他需要输入一些不是白色的字符space 得到 scanf
到 return,所以即使他不需要或不希望程序读取第三个参数,他也需要输入 一些东西 scanf can/will 识别为输入中 whitespace 的结尾,与格式字符串中的尾随 space 匹配。 "something" 是什么并不重要,除了它不能是 white-space (space, new-line, tab, vertical tab, 可能其他取决于语言环境)。
下面的文字是我最初的回答,但经过讨论和重读,我认为它没有抓住 OP 可能想问的重点,所以虽然它说的是真的,但我怀疑它有多大实际用处.
C 和 C++ 基本上都将标准输入视为一个文件。他们不能(也不会尝试)控制您输入标准输入的数据。他们所能做的就是在阅读数据后决定如何处理这些数据。
在这种情况下,您根本没有要求读取该数据,因此它被忽略了。
程序的标准输入有点像程序是一个人站在繁忙的街道上,周围有数百人。该程序可以听他们说什么或不听他们说什么——但实际上不能做任何事情来阻止他们所有人说话。同样,程序可以读取或不读取某些输入,但无法阻止您输入它不需要或不关心的额外输入。
你写的方式 scanf
是完全错误的,应该避免。
而不是你的scanf
:
scanf("%i %i ",&a,&b);
你应该使用这个:
scanf("%i%i", &a, &b);
避免在 scanf
.
您想要的工作代码:
#include <iostream>
using namespace std;
#include <stdio.h>
int main(int argc, const char *argv[]) {
int a, b;
scanf("%i%i", &a, &b);
printf("a-> %i", a);
printf("b-> %i", b);
return 0;
}
在 C 中,调用者和被调用者必须就在调用之前压入堆栈的参数数量达成一致。
scanf
也不例外,它采用可变数量的参数,基本上由提供的格式字符串决定。 scanf
扫描格式说明符并期望每个指定格式都有一个对应的变量地址。
在您编写的测试程序中
scanf("%i %i ",&a,&b);
表示从输入缓冲区stdin中取出两个整数,放在a和b的地址上。然而,没有什么可以阻止您在 stdin 中写入更多字符,这些可以通过随后调用 scanf 来读取。
对于键盘输入,通常应避免使用 scanf,而是使用 fgets(),它允许您指定输入的最大大小,然后使用 sscanf() 从缓冲区读取。
char buffer[128];
if (fgets(buffer,sizeof(buffer),stdin) != NULL)
{
if (sscanf( buffer, "%i %i", &a, &b) == 2)
{
printf( "the numbers are %i and %i\n", a,b );
}
}
请注意,您包含了 C++ header 但根本没有使用它,您可能想要删除该包含或完全更改代码并改用 cin/cout。
虽然 scanf 方便易用,但请注意它
- 不会为您检查输入参数(因此,您有责任检查用户的输入参数)
因此,当你做
scanf("%i %i ",&a,&b);
scanf 只会 'scan' 进行输入,直到它认为完成为止。
因此,您应该像这样检查输入
if (scanf("%i %i", &a, &b) != 2) {
/* throw error and exit */
}