【问题标题】:How does a scanf() inside printf() work?printf() 中的 scanf() 是如何工作的?
【发布时间】:2018-06-12 17:23:28
【问题描述】:
#include<stdio.h>
int main(){

        int n;
        printf("%d\n",scanf("%d",&n));
        return 0;
}

我想知道为什么这个程序的输出总是'1'?! 这里到底发生了什么?

【问题讨论】:

  • scanf 从函数返回一个值:转换的项目数,正如手册页将告诉您的那样。手册页应该是您使用任何功能的第一站。
  • 您没有在 scanf() 上阅读任何内容,是吗? en.cppreference.com/w/c/io/fscanf
  • 当你输入一个非数字字符时你会得到什么答案?

标签: c printf scanf


【解决方案1】:

我怀疑你想使用

int n;
scanf("%d", &n);
printf("%d\n", n);

但是你写的等价于

int n;
int num = scanf("%d", &n); // num is the number of successful reads.
printf("%d\n", num);

【讨论】:

  • 我提出问题的目的只是想知道结果背后的原因,因为我在书中遇到了这样一个客观的问题......谢谢
  • @jishnupramod,如果我是你,我会放弃那本书。一本书应该教授语言的原则和基本方面。使用这样的问题就是我所说的“智能组合”。这不是教学。
【解决方案2】:

该程序几乎完全等同于

#include <stdio.h>

int main() {
    int n;
    int r = scanf("%d", &n);
    printf("%d\n", r);
    return 0;
}

所以如果你运行这个程序,并且如果你输入(比如说)45,那么scanf 将读取 45,并将其分配给n,并返回 1 告诉你它已经这样做了。程序打印由scanf 返回的值 1(它不是数字读取scanf!)。

尝试运行程序并键入“A”。在这种情况下,scanf 应该返回,并且您的程序应该打印 0。

最后,如果可以的话,尝试运行程序并且不给它任何输入。如果您使用的是 Unix、Mac 或 Linux,请尝试在运行程序后立即输入 control-D(即不输入任何其他内容),或者在输入重定向的情况下运行它:

myprog < /dev/null

在 Windows 上,您可以键入 control-Z(可能后跟 Return 键)来生成文件结束条件。在任何这些情况下,scanf 应该返回,并且您的程序应该打印 -1。

【讨论】:

    【解决方案3】:

    @jishnu,好问题,您得到的输出也是正确的,因为您只从标准输入 (stdin) 中读取一个值。

    scanf() 读取标准输入提供的值并返回从标准输入(键盘)成功读取的值的数量。

    在 C 中,printf() 返回成功写入输出的字符数,scanf() 返回成功读取的项目数。访问https://www.geeksforgeeks.org/g-fact-10/ 并阅读更多相关信息。

    查看以下 2 个代码示例。

    http://rextester.com/HNJE76121 在线尝试以下代码。 //clang 3.8.0

    #include<stdio.h>
    int main(){
    
        int n, n2;
        printf("%d\n",scanf("%d%d",&n, &n2));   //2
        return 0;
    }
    

    在您的代码中,scanf() 仅从键盘 (stdin) 读取 1 个值,这就是输出为 1 的原因。

    //clang 3.8.0
    
    #include<stdio.h>
    int main(){
    
        int n;
        printf("%d\n",scanf("%d",&n));   //1
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      在您的程序中,当scanf 成功地将某个值取入 n 时,scanf 返回 1,这就是为什么您总是从您的 printf("%d\n",scanf("%d",&amp;n)); 获得 1。 你应该像下面这样修改你的代码

      #include<stdio.h>
      int main(){
      
              int n;
              scanf("%d",&n);
              printf("%d\n",n);
              return 0;
      }
      

      【讨论】:

      • 我的问题只是想知道结果背后的原因...谢谢
      【解决方案5】:

      man scanf

      返回值

      这些函数返回成功匹配和分配的输入项的数量,该数量可能少于提供的数量,在早期匹配失败的情况下甚至为零。

      在你的程序中,它只匹配 1 个输入,所以函数 scanf 将返回 1,如果你输入一个可以匹配 %d 的合法值,否则它将返回 0。

      在你的情况下,你可能总是满足这个要求,所以它总是返回 1。

      【讨论】:

      • 输入格式规范为%d。如果无法从输入中提取整数,则scanf 返回0 - 这就是返回值的用途。那不是“总是 1”。
      • @WeatherVane 我以为问题的作者总是会输入合法的%d...这是我的错误,谢谢。
      • 是的,返回值的目的是检测用户是否输入了可以转换为类型的值。
      【解决方案6】:

      scanf 返回成功转换和分配的数量。在您的情况下,您只扫描一个参数,因此scanf 将在成功时返回1,在匹配失败 时返回0(其中第一个非空白输入字符不是十进制数字),或 EOF 在文件结尾或错误。

      当您调用printf 时,它的每个参数都求值,并将结果传递给函数。在这种情况下,评估涉及调用scanf 函数。然后将scanf 返回的值传递给printf

      本质上和写是一样的

      int count = scanf( "%d", &n );
      printf( "%d\n", count );
      

      对于傻笑,看看当你输入 abc 或输入 CtrlD(或 CtrlZ 在 Windows 上)。

      注意printf返回一个值(写入流的字节数),所以你可以写一些荒谬的东西1

      printf( "num bytes printed = %d\n", printf( "num items read = %d\n", scanf( "%d", &n ) ) );
      


      1. 笑话。不要那样做。

      【讨论】:

        【解决方案7】:

        scanf 返回成功转换的数量。 尝试将您的scanf 更改为如下所示.... 输入两个有效整数后,您会注意到打印 2。

        int n1 =0;
        int n2 =0;
        int i = scanf("%d %d",&n1,&n2);
        

        【讨论】:

        • 一个更准确的术语是“成功的转化”。
        • 是的。我会改的。
        【解决方案8】:

        C 编程中,scanf() 从键盘stdin() 获取输入并返回读取成功的输入数 而printf() 返回写入stdout() 的字符数,stdout() 是显示监视器。

        在您的程序中,scanf() 仅读取一个输入,该输入将被返回并由printf() 打印。因此,无论输入是什么,输出始终为 1,因为它只读取一个输入。

        下面看看这个C程序:

        #include<stdio.h>
        int main(){
        
                int n, n2;
                printf("%d\n",scanf("%d %d",&n,&n2));
                return 0;
        }
        

        它使用scanf()stdin()获取输入或读取两个整数,因此输出将始终为2。

        **注意:如果您的输入不是整数,则输出为 0,因为它只读取整数。

        【讨论】:

          【解决方案9】:

          scanf() 的文档说返回值是:

          Number of receiving arguments successfully assigned (which may be zero in case a matching failure occurred before the first receiving argument was assigned), or EOF if input failure occurs before the first receiving argument was assigned.

          您想要的代码是:

          #include<stdio.h>
          int main(){
          
              int n;
              scanf("%d",&n);
              printf("%d\n",scanf("%d",&n));
              return 0;
          }
          

          【讨论】:

          • 我的问题只是想知道结果背后的原因...谢谢
          【解决方案10】:

          如果您使用此代码作为示例, 它显示:警告:函数'printf'的隐式声明[-Wimplicit-function declaration]

          int main()
          {
          char b[40]; 
          printf(" %d", scanf("%s", b));
          getchar();
          } 
          

          返回值:-1

          printfscanf 等函数的输出可以用作另一个函数的参数。

          【讨论】:

          • 您的意思是“返回值”,而不是“输出”。我不清楚你想用隐式声明警告说什么。
          • 对,就是返回值!
          【解决方案11】:

          scanf() 是一个整数返回类型函数。它返回其中的转换字符总数。例如,如果一个语句写成:

          int c;
          c=scanf("%d %d %d");
          printf("%d",c);
          

          那么这个程序的输出将是3。 这是因为scanf() 是整数返回类型函数,它返回的转换字符总数为3 转换字符,它将返回3c。 所以在你的代码中scanf()1 返回到printf(),因此程序的输出是1。 这是因为如果在printf() 中使用了多个语句,则执行顺序从右到左开始。 因此scanf()首先被执行,然后是printf()

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-25
            相关资源
            最近更新 更多