scanf需要额外的参数为什么?

时间:2015-06-09 17:26:15

标签: c++ c scanf

我是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

6 个答案:

答案 0 :(得分:6)

  

scanf需要额外的参数原因?

这不是一个准确的结论。额外输入保留在输入流中。它不会被~/.rbenv/shims:/usr/local/bin:/usr/bin:/bin使用。它在程序结束时被丢弃。

如果您有另一条scanf行,

scanf

scanf("%d", &c); 将被读入40

答案 1 :(得分:4)

在与本杰明林德利的评论中讨论后,我想我原本可能误解了这个问题的意图。

也许问题不是为什么你允许输入第三个输入,而是关于为什么你需要在{{1}之前输入第三个输入很满意。

在这种情况下,我认为@Dale Wilson的答案基本上是正确的(尽管解释有点简短)。

scanf格式字符串中的空格表示scanf将跳过所有连续的空白区域。按下键盘上的回车键通常被解释为在输入流中输入换行符,这被认为是空格。

使用格式字符串中的尾随空格,他需要输入一些空格的字符才能让scanf返回,所以即使他没有不需要或希望程序读取第三个参数,他需要输入某些,scanf可以/将识别为输入中的空格的末尾,该格式是由格式中的尾随空格匹配的串。除了它不能是空白(空格,换行符,制表符,垂直制表符,可能还有其他取决于语言环境)这一事实之外,“某物”是什么并不重要。

下面的文字是我最初的答案,但经过讨论和重读之后,我认为它错过了OP可能要提出的问题,所以虽然它说的是真的,但我怀疑它是否真的有用。 / p>

C和C ++都将标准输入视为基本文件。他们不能(也不试图)控制您输入标准输入的数据。他们所能做的就是决定在读取数据之后做什么(如果有的话)。

在这种情况下,您根本没有要求读取该数据,因此它被忽略了。

节目的标准输入有点像节目是站在繁忙的街道上与周围数百人一起的人。该程序可以听取他们所说或不听的内容 - 但实际上并没有做任何事情来阻止所有人说话。同样在这里,程序可以读取或不读取某些输入,但是无法阻止您输入它不想要或不关心的额外输入。

答案 2 :(得分:3)

在第二个%i之后,您的格式有空格。 scanf将读取额外数据以匹配空间。删除空格,它应该按预期工作。

答案 3 :(得分:1)

您编写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;
}

答案 4 :(得分: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 ++标头但根本不使用它,您可能希望删除包含或完全更改代码并改为使用cin / cout。

答案 5 :(得分:0)

虽然scanf方便易用,但请注意

  • 不会为您检查输入参数(因此,您有责任检查用户的输入参数)

因此,当你做

scanf("%i %i ",&a,&b);

scanf只是扫描&#39;输入,直到它认为它已完成。

因此,你应该像这样检查输入

if (scanf("%i %i", &a, &b) != 2) {
    /* throw error and exit */
}