【问题标题】:How does scanf and getchar work together?scanf 和 getchar 如何协同工作?
【发布时间】:2021-12-09 19:44:18
【问题描述】:

我很困惑 scanf 如何与 getchar 一起工作。我假设 scanf 可以获取用户输入,然后当用户按下输入时,它会分别分配输入。同时,getchar 通过获取每个字符并将其分配给分配给 getchar 的变量来工作。查看这段代码:

#include <stdio.h>

int main (){
    int num, i;
    char ch;
    printf("Enter an expression: ");
    scanf("%d", &i);
    while ((ch = getchar()) != '\n'){
        if (ch == '+'){
            scanf("%d", &num);
            i += num;
            break;
        }
    }
    printf("%d", i);
}

我不应该输入 3 次吗?第一个scanf,然后是getchar,然后是最后一个scanf,还是我在这里遗漏了一些关键?我是 C 新手,希望你不要介意我的这个(可能是愚蠢的)问题 :)

【问题讨论】:

  • 关键是了解scanf() 如何处理格式字符串和输入流中的空格,这随格式说明符的不同而不同。基线是混合不同的输入函数:如果你必须这样做来混淆scanf()`的工作方式,那么首先不要使用scanf()
  • scanf 系列非常适合解析简单的输入。一旦它不简单,人们就应该远离scanf,而不是相信这是“方式”,因为他们被教导了什么。将scanf 用于表达式听起来正是这个问题。使用词法分析器和解析器生成器来处理更复杂的语法。

标签: c scanf getchar


【解决方案1】:

scanf在用户按下回车时不参与传输数据。

C 程序有数据流。 (即使它们使用FILE * 类型处理,它们是流,而不是文件。)scanf 从标准输入流中读取。通常,标准输入流连接到终端设备(过去是物理终端设备,现在更可能是软件终端窗口)。终端设备具有关于何时将用户键入的数据发送到流的协议。同样最常见的是,当用户按下回车键时,他们输入的数据将被发送到流中。此外,在 Unix 系统上,按 control-D 会将输入的数据发送到流中。

为了完成它的工作,scanf 向流请求一个字符。然后它分析字符如何匹配它正在处理的转换。例如,当scanf 正在处理%d 转换时,它预计开头可能有一些空白字符(它会跳过),然后可能是“+”或“-”,然后是一些数字。任何其他字符都会停止转换。因此,当scanf 开始进行%d 转换时,它会得到一个字符。如果没有可用的字符,可能是因为用户键入了一些内容但尚未按下回车键,那么scanf 就坐在那里等待字符到达。当用户按下回车键时,scanf 获取第一个字符。

请注意,scanf 没有参与等待按下回车。那是终端的功能。此时scanf只有第一个字符,不知道有没有回车。

scanf 读取数字后,它会读取下一个字符。当该字符与%d 模式不匹配时,它会将字符放回流中。因此,如果用户键入“123+456”,scanf 会处理“123”,获取“+”,拒绝“+”,并将“+”推回流中。

然后getchar 得到“+”并返回它。

然后后面的scanf 读取“456”。它还看到终端为输入键放入流中的换行符,然后拒绝它并将其推回流中。

【讨论】:

  • 哇,这为我清除了这么多东西,所以我假设所有可以输入的函数共享同一个流是正确的吗?这也是他们所说的输入缓冲区吗?
  • @airismything:是的,程序中使用标准输入流的每个函数都共享同一个流(当程序打开其他流时,其他流也一样)。流内部通常有一些缓冲区,但可以将流设置为不使用缓冲区。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 2014-08-05
  • 2020-01-14
  • 2012-12-21
  • 2013-01-19
  • 2018-07-08
相关资源
最近更新 更多