为什么在使用scanf输入这些值时在%d和%c之间放置空格

为什么在使用scanf输入这些值时在%d和%c之间放置空格,c,C,我是C的初学者,我正在写一个代码来打印用户输入字符的正方形 通常,当我们需要使用scanf()输入两个整数(比如x和y)时,我们编写这个scanf(“%d%d”、&x和&y),但是根据我代码的需要,我应该输入一个整数(比如m)和一个字符(比如ch) 我写的是scanf(“%d%c”,&x,&ch),但它有一个错误,当我执行程序时,它只要求输入整数值,然后它就停止执行 我搜索了这个,发现我需要在%d和%c之间加上空格作为scanf(“%d%c”、&x和&ch) 有人能解释一下为什么我们需要在这两者

我是C的初学者,我正在写一个代码来打印用户输入字符的正方形

通常,当我们需要使用
scanf()
输入两个整数(比如x和y)时,我们编写这个
scanf(“%d%d”、&x和&y)
,但是根据我代码的需要,我应该输入一个整数(比如m)和一个字符(比如ch)

我写的是
scanf(“%d%c”,&x,&ch)
,但它有一个错误,当我执行程序时,它只要求输入整数值,然后它就停止执行

我搜索了这个,发现我需要在
%d
%c
之间加上空格作为
scanf(“%d%c”、&x和&ch)


有人能解释一下为什么我们需要在这两者之间加空格吗?

格式字符串中空白字符的含义(从):

空白字符:函数将读取并忽略在下一个非空白字符之前遇到的任何空白字符(空白字符包括空格、换行符和制表符——请参见isspace)。格式字符串中的单个空白验证从流中提取的任何数量的空白字符(包括无)

当您的代码为:

scanf("%d%c", &x, &ch)
你进去了吗

10
10
5 #
在您的控制台中:

  • 10
    被读取并存储在
    x
  • 换行符被读取并存储在
    ch
  • 如果你使用

    scanf("%d %c", &x, &ch)
    
    你进去了吗

    10
    
    10
    
    5 #
    
  • 10
    被读取并存储在
    x
  • 使用换行符和其他空白字符。程序等待非空白字符。一旦输入一行且该行中至少存在一个非空白字符,该行的第一个非空白字符将被读入
    ch
    。这是因为
    stdin
    通常是行缓冲的

  • 在尝试读取任何内容之前,
    scanf
    中几乎所有的格式说明符都会自动跳过所有空白。例如,这就是
    %d
    的工作方式(以及
    %s
    %f
    和大多数其他说明符)。但是,
    %c
    是此行为的一个例外<代码>%c
    不跳过空白。如果输入数据包含空白字符,
    %c
    会很高兴地将该字符读入
    ch
    变量中

    这很可能就是你的情况。如果你进去

    10
    
    10
    
    5 #
    
    要创建5x5平方的
    #
    s,
    %d
    说明符将
    5
    读入
    x
    并停止读取空格字符。然后
    %c
    将该空格字符读入
    ch
    。然后您的程序将继续运行,而
    #
    未读。很有可能您的程序的其余部分实际上按预期工作。只是因为
    ch
    是一个空格字符,所以它会显示一个5x5平方的空格字符,这些字符是不可见的:)为了使
    scanf
    按其原始形式正常工作,您必须以

    5#
    
    但是,确保您的
    scanf
    实际将
    #
    字符读入
    ch
    的更好方法是在读取
    ch
    之前明确要求
    scanf
    跳过所有空格。在
    scanf
    中,这是通过在格式字符串中插入任何空白字符(空格、换行符、制表符等)来完成的。这个

    scanf("%d %c", &x, &ch);
    
    将强制
    scanf
    跳过
    5
    之后的空格,并将
    #
    读入
    ch
    。这也适用于这样的输入

    5              #
    
    5
      #
    
    甚至像这样

    5              #
    
    5
      #
    
    因为
    scanf
    将自动跳过所有空白,直到它到达
    。还请注意,即使使用更新的格式,输入中也不需要空格,这意味着此输入

    5#
    
    仍将使用更新的
    scanf

    您也可以使用这些变体

    scanf("%d\t%c", &x, &ch);
    scanf("%d\n%c", &x, &ch);
    scanf("%d     %c", &x, &ch);
    scanf("%d \n \t %c", &x, &ch);
    

    实现同样的目标。它们都是等价的。第一个变体(带空格)看起来更好。

    仔细阅读
    %d
    %c
    和``(空格)所做的事情:它们各自做不同的、相当复杂的事情。“一旦输入了一个非空白字符,它将被读入ch。”这是正确的,除了
    stdin
    通常是行缓冲的和
    scanf()
    在后续换行之前不会获取非空白字符。谢谢您的回答。我很感激。@pranav,已经一年半了:)希望你问这个问题时这个答案有用。我发现这个答案比公认的答案更具信息性。多谢各位+1.