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
这不是一个准确的结论。额外的输入留在输入流中。它不被scanf为什么需要额外的参数?
scanf
消耗。它在程序结束时被丢弃。
如果你有另一个scanf
行,
scanf("%d", &c);
值40
将被读入c
在第二个%i之后有一个空格。scanf
将读取额外的数据来匹配空间。删除空格,它应该像你期望的那样工作。
在评论中与Benjamin Lindley讨论后,我想我最初可能误解了这个问题的意图。
也许问题不在于为什么允许输入第三个输入,而在于为什么在满足scanf
之前需要输入第三个输入。
在这种情况下,我认为@Dale Wilson的答案基本上是正确的(尽管解释有点短)。
scanf
格式字符串中的空格意味着scanf将跳过所有连续的空白。按下键盘上的enter键通常被解释为在输入流中输入一个新行字符,这被认为是空白。
对于格式字符串中的尾随空格,他需要输入一些而不是空白的字符来让scanf
返回,所以即使他不需要或不希望程序读取第三个参数,他需要输入一些, scanf可以/将识别为与格式字符串中的尾随空格匹配的输入中的空白的结束。"某些东西"是什么并不重要,重要的是它不能是空白(空格、新行、制表符、垂直制表符,根据语言环境可能还有其他)。
下面的文字是我最初的回答,但经过讨论和重读,我认为它错过了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 %in", a,b );
}
}
请注意,您包含了一个c++头文件,但根本没有使用它,您可能想要删除该包含或完全更改代码,并使用cin/cout来代替。
虽然scanf方便且易于使用,但请注意它
- 不为您检查输入参数(因此,检查用户输入参数是您的责任)
因此,当你执行
时scanf("%i %i ",&a,&b);
scanf将只'扫描'输入,直到它认为它已经完成。
因此,您应该像这样检查输入
if (scanf("%i %i", &a, &b) != 2) {
/* throw error and exit */
}
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 为什么我应该在scanf()-家族成员中包含一个长度修饰符作为参数?有什么好处?使用长度修改器进行扫描的作用
- 不能使用嵌套结构中的联合元素作为 scanf() 的参数来存储所需的值
- 使用带有多个参数的 scanf
- 我们是否可以创建一个类似scanf的函数,当所有参数都填充时返回true,否则返回false,而不循环遍历所有变量?
- Scanf需要额外的参数