【问题标题】:C - How scanf inputs work and how it iterates in loops?C - scanf 输入如何工作以及它如何在循环中迭代?
【发布时间】:2020-09-21 01:22:08
【问题描述】:

我知道scanf()的基础;需要转换说明符 % 和变量地址来存储输入值 &。

在进行分配时,有一项任务涉及输入任意数量的值,例如: 5 4 3 2 1

进入scanf,然后打印出输入的整数对应的符号个数(例如'?'),所以终端会显示为:

5 4 3 2 1
?????
????
???
??
?

在这种情况下,我将 scanf 置于 while 循环中:

int i, num;
while(scanf("%d",&num)==1){
   printf("%d",num);
   for (i=0; i<num; i++){
      printf("?");
   }
   printf("/n");
}

当许多来源指定 scanf 只接受一个整数直到它读取一个空格时,我完全困惑 scanf 如何在一个输入行 (5 4 3 2 1) 中读取多个整数。从这个角度来看,我的理解是分隔整数的空格表示前一个整数之后的新迭代? 当我试图追踪打印的工作原理时,它打印为:

5 4 3 2 1
5?????
4????
3???
2??
1?

...所以我的问题是 scanf 如何将所有这些整数在一行中“保存”到“num”并将相应符号的每个打印到输入后给定的值?如果没有数组,整数不会替换变量中的前一个吗?

对不起,如果这个问题没有意义 - 对编码来说还是很陌生。谢谢!

【问题讨论】:

    标签: c loops input scanf


    【解决方案1】:

    您对scanf 的理解是正确的,scanf 只取一个整数,直到它读取一个空格。

    这里让您感到困惑的是算法的工作原理。您的算法首先读取整数 5 并“立即”打印五个 ?。它继续读取 4,打印四个 ?,读取 3,打印三个 ?,以此类推。

    【讨论】:

      【解决方案2】:

      scanf 将该行存储在内部缓冲区中。如果缓冲区不为空,它会尝试从缓冲区中读取并删除成功读取的部分;如果缓冲区为空,则等待用户输入。在外循环的第一次迭代 (while) 中,缓冲区为空。您输入“5 4 3 2 1”,因此缓冲区包含它。第一个sscanf("%d",&amp;num)从缓冲区中读取第一个整数,即5;缓冲区现在包含“4 3 2 1”。在第二次迭代中,您读取 4,缓冲区将为“3 2 1”。这种情况一直持续到缓冲区用完为止。此时您的程序继续;它只是等待更多的输入。

      【讨论】:

        【解决方案3】:

        scanf'读取'来自标准输入流stdin 的字符(如果还没有,它会提示用户输入要添加的内容),并根据转换说明符将它们转换为格式在格式字符串中使用。

        您可以将stdin 视为内存中的一系列字符,每次用户在终端中键入内容并按 Enter 时,键入的内容都会添加到stdin

        因此,在您的情况下,当您在终端中键入 5 4 3 2 1 并按 Enter 键时,stdin 将收到字符序列 "5 4 3 2 1\n"(请注意,当您按 Enter 键时添加了新行字符)。

        然后是 scanf("%d",&amp;num),它只需要 1 个十进制整数,从 stdin“读取”和“消耗”形成一个连续十进制整数的相关字符。

        在这种情况下,5 在第一次执行scanf 时被读取," 4 3 2 1\n" 留在stdin 中。然后在满足条件时执行循环语句。第二次执行scanf 时,前导空格被%d 说明符丢弃并读取4,将" 3 2 1\n" 留在stdin 中。依此类推,直到无法从stdin 读取十进制整数...

        【讨论】:

          【解决方案4】:

          在没有数组的情况下,整数不会替换变量中的前一个吗?

          这里根本不需要数组。

          scanf() 函数取值(假设包括空格),并将它们一一保存到变量num 中。如果您使用调试器(假设使用 GDB)并在 while() 中设置断点,您将通过逐步了解变量 num 在每次迭代中更改并且 for 循环运行到 num已到达。

          下面提供了使用调试器进行两次迭代的示例(关注左上角的num):

          迭代 1:

          迭代 2:

          【讨论】:

            猜你喜欢
            • 2018-04-15
            • 1970-01-01
            • 2021-09-17
            • 2023-03-25
            • 1970-01-01
            • 2022-10-15
            • 1970-01-01
            • 2010-11-20
            • 1970-01-01
            相关资源
            最近更新 更多