scanf("%[^\n]",name); 的区别和 scanf(" %[^\n]",name);

The differences of scanf("%[^\n]",name); and scanf(" %[^\n]",name);

这不是错字。对于没有注意到的人,第二个有 space,第一个没有 space。

当我做这样的作业时,它发生在我身上:

#include<stdio.h>

int main(){
int id,d,m,y;
char name[30];
printf("\tSTUDENT ID\t\t: ");scanf("%d",&id);\
printf("\tNAME\t\t: ");scanf("%[^\n]",&name);
printf("\tDATE OF BIRTH\t: ");scanf("%d/%d/%d",&d,&m,&y);
}

当我执行该代码时,"NAME" 部分跳转到输入 "DATE OF BIRTH" 部分

但是,当我更改 scanf("%[^\n]",&name);进入 scanf(" %[^\n]",&name); 一切正常。

怎么会这样?我好像不太明白其中的区别

注意:你可以试一下,然后告诉我它在你身上是否正常,可能只是我的电脑问题或其他原因

当您将 space 放入 scanf formatting string, then scanf will match it with any whitespace, of any length. So by putting that leading space in the format, scanf 时,实际上会跳过输入中的前导白色 space(包括前一个输入的换行符)。

示例:

假设您的简单程序的输入是

123
Joe Bloggs
22/9/15

第一次调用 scanf 读取数字 123,但在输入缓冲区中留下您输入的换行符以结束该行输入。当您下次调用 scanf 获取名称时,scanf 将首先看到换行符结束 return 立即(不使用它,因此它仍然在输入缓冲区中)。然后调用 scanf 读取日期,"%d" 格式自动跳过前导白色 space,因此 scanf 会消耗换行符,但随后会看到名称,它会不匹配十进制整数的格式并退出,不读取数据。

通过在读取名称时将前导 space 添加到格式中,第二个 scanf 调用将读取(并忽略)前一个输入的换行符,然后正确读取名称,将第二行的终止换行符留在输入缓冲区中,然后在下一次调用 scanf 时跳过,后者会正确读取日期。

scanf() 函数族有 3 个标准格式说明符,它们不会自动跳过白色 space。他们是:

  1. %c
  2. %[] — 扫描集
  3. %n

所有其他(标准)格式说明符跳过前导白色 space。

通过在 %[] 之前包含白色 space,您可以跳过前导白色 space,因为 scanf() 系列格式字符串中只有一个白色 space (在扫描集之外)匹配输入中的零个或多个白色 space 字符。请特别注意,这意味着如果您键入一些空行(只需点击 return),白色 space 将继续愉快地忽略(更准确地说,丢弃)输入,直到非白色 - space 个字符已输入。只有这样 scanf() 才会开始处理扫描集。