19152

96 分钟

#C 语言标准库函数 scanf

/********************************************* * @brief 从标准输入中获取输入 * @param format 格式字符串 * @param ... 可变长度参数,要打印的变量 * @return 打印的字符数量 ********************************************/ int scanf(const char* restrict format, ...);

说明

从标准输入中获取输入。

参数

  • format - 格式化字符串,指向以空字符(\0)结尾的字符串指针,指定如何解释数据
    • 普通字符直接输入,如果不匹配则导致失败
    • 转义字符按照转义打印
    • 空格字符将读取输入的所有连续空白字符,包括空格,\n\t
    • % 开头的 格式占位符,按照指定格式读取输入并写入后续相应位置的参数
  • ... - 可变长度参数,为接收输入的地址,需要与 format 参数中的格式占位符一一对应

返回值

  • 成功分配的接收参数的数量
  • 分配第一个接收参数之前发生匹配失败时返回 0
  • 分配第一个接收参数之前发生输入失败时返回 EOF

#示例

#include <stdio.h> int main(void) { int age; float height; double weight; char initial; char name[50]; // 存储姓名(无空格) char sentence[100]; // 存储带空格的整行输入 // 示例1:读取整数、浮点数、字符 printf("请输入您的年龄、身高(米)、体重(kg)和姓氏首字母(用空格分隔):"); int items_read = scanf("%d %f %lf %c", &age, &height, &weight, &initial); if (items_read != 4) { printf("输入错误!请确保输入4个值(年龄 身高 体重 首字母)。\n"); while (getchar() != '\n'); // 清空输入缓冲区 } else { printf("结果:您今年%d岁,身高%.2f米,体重%.1lfkg,姓名首字母是'%c'。\n", age, height, weight, initial); } // 示例2:读取名称首字母(无空格) printf("\n请输入您的名称首字母(不要带空格):"); if (scanf("%49s", name) == 1) { // 限制长度防止溢出 printf("您好,%s!\n", name); } else { printf("未能读取姓名。\n"); } // 示例3:读取整行(允许空格) printf("\n请输入一句话(可以带空格):"); while (getchar() != '\n'); // 清空之前的输入缓冲区 if (scanf("%99[^\n]", sentence) == 1) { // 读取直到换行符 printf("您输入的是:「%s」\n", sentence); } else { printf("未接收到输入。\n"); } // 示例4:安全读取整数(错误处理) int number; printf("\n请输入一个整数:"); while (scanf("%d", &number) != 1) { // 循环直到输入有效 printf("输入无效!请重新输入整数:"); while (getchar() != '\n'); // 清空缓冲区 } printf("您输入的整数是:%d\n", number); return 0; }

运行结果:

请输入您的年龄、身高(米)、体重(kg)和姓氏首字母(用空格分隔):17 160 50 h 结果:您今年17岁,身高160.00米,体重50.0kg,姓名首字母是'h'。 请输入您的名称首字母(不要带空格):bc 您好,bc! 请输入一句话(可以带空格):hello world 您输入的是:「hello world」 请输入一个整数:233 您输入的整数是:233

#格式占位符

格式占位符以 %[*][宽度][长度修饰]说明符 的形式出现。

  • * 是赋值抑制符,表示这部分输入不赋值给接收参数
  • 宽度:输入的最大字符数
  • 长度修饰:表示类型长度,例如 %dint,而 %ldlong
说明符
说明
参数类型hhhllljztL
%百分号(%)本身---------
c单个字符char*--wchar_t-----
s字符串,以空字符(\0)结尾char*--wchar_t*-----
d有符号十进制整数int*signed char*short*long*long long*intmax_t*size_t*ptrdiff_t*-
i有符号十进制整数,同 %dint*signed char*short*long*long long*intmax_t*size_t*ptrdiff_t*-
u无符号十进制整数unsigned int*unsigned char*unsigned short*unsigned long*unsigned long long*uintmax_t*size_t*ptrdiff_t*-
o无符号八进制整数unsigned int*unsigned char*unsigned short*unsigned long*unsigned long long*uintmax_t*size_t*ptrdiff_t*-
x无符号十六进制整数,字母小写unsigned int*unsigned char*unsigned short*unsigned long*unsigned long long*uintmax_t*size_t*ptrdiff_t*-
X无符号十六进制整数,字母大写unsigned int*unsigned char*unsigned short*unsigned long*unsigned long long*uintmax_t*size_t*ptrdiff_t*-
f浮点数,字母小写float*--double*----long double*
F浮点数,同 %ffloat*--double*----long double*
e浮点数,科学计数法,字母小写float*--double*----long double*
E浮点数,科学计数法,字母大写float*--double*----long double*
g浮点数,省略小数末尾的 0,值较大时使用科学计数法,字母小写float*--double*----long double*
G浮点数,省略小数末尾的 0,值较大时使用科学计数法,字母大写float*--double*----long double*
a浮点数,十六进制,科学计数法,字母小写float*--double*----long double*
A浮点数,十六进制,科学计数法,字母大写float*--double*----long double*
p指针地址void*--------
n将当前已读取的字符数量写入参数中int*siged char*short*long*long long*intmax_t*size_t*ptrdiff_t*-
[set]匹配字符集合,类似正则表达式的中括号char*--wchar_t*-----

匹配字符集合 [set] 用于指定匹配某些字符。例如:

  • %[abc] 表示读取连续的多个 abc,遇到其它字符时停止匹配
  • %[^abc] 表示读取连续的多个除了 abc 以外的字符,遇到 abc时停止匹配
  • %[^\n] 表示读取连续的多个除了 \n 以外的字符,遇到 \n 时停止匹配;也就是读取整行
  • %[a-z] 表示读取连续的多个小写字母,遇到其它字符时停止匹配
  • %[0-9] 表示读取连续的多个数字,遇到其它字符时停止匹配
  • %9[0-9] 表示读取连续的多个数字,遇到其它字符时停止匹配;最多读取 9 个字符
  • %*[^A-Za-z] 表示读取连续的多个字母,遇到其它字符时停止匹配;并将这些输入丢弃

#特殊格式宏

由于 C 语言中类型的长度不是固定的。反过来说,固定长度的类型,其原始类型是不确定的。

例如 int32_t 在某些环境下是 int,另外某些环境下是 long;前者使用 scanf 读取时应使用 %d,而后者应使用 %ld

为了方便,可以使用以下宏来标识格式。

scanf 格式标准说明
SCNd8C99scanf 中用于输入 int8_td 格式(有符号十进制)
SCNd16C99scanf 中用于输入 int16_td 格式
SCNd32C99scanf 中用于输入 int32_td 格式
SCNd64C99scanf 中用于输入 int64_td 格式
SCNdPTRC99scanf 中用于输入 intptr_td 格式
SCNdMAXC99scanf 中用于输入 intmax_td 格式
SCNdFAST8C99scanf 中用于输入 int_fast8_td 格式
SCNdFAST16C99scanf 中用于输入 int_fast16_td 格式
SCNdFAST32C99scanf 中用于输入 int_fast32_td 格式
SCNdFAST64C99scanf 中用于输入 int_fast64_td 格式
SCNdLEAST8C99scanf 中用于输入 int_least8_td 格式
SCNdLEAST16C99scanf 中用于输入 int_least816_td 格式
SCNdLEAST32C99scanf 中用于输入 int_least832_td 格式
SCNdLEAST64C99scanf 中用于输入 int_least864_td 格式
SCNi8C99scanf 中用于输入 int8_ti 格式(有符号十进制)
SCNi16C99scanf 中用于输入 int16_ti 格式
SCNi32C99scanf 中用于输入 int32_ti 格式
SCNi64C99scanf 中用于输入 int64_ti 格式
SCNiPTRC99scanf 中用于输入 intptr_ti 格式
SCNiMAXC99scanf 中用于输入 intmax_ti 格式
SCNiFAST8C99scanf 中用于输入 int_fast8_ti 格式
SCNiFAST16C99scanf 中用于输入 int_fast16_ti 格式
SCNiFAST32C99scanf 中用于输入 int_fast32_ti 格式
SCNiFAST64C99scanf 中用于输入 int_fast64_ti 格式
SCNiLEAST8C99scanf 中用于输入 int_least8_ti 格式
SCNiLEAST16C99scanf 中用于输入 int_least816_ti 格式
SCNiLEAST32C99scanf 中用于输入 int_least832_ti 格式
SCNiLEAST64C99scanf 中用于输入 int_least864_ti 格式
SCNu8C99scanf 中用于输入 uint8_tu 格式(无符号十进制)
SCNu16C99scanf 中用于输入 uint16_tu 格式
SCNu32C99scanf 中用于输入 uint32_tu 格式
SCNu64C99scanf 中用于输入 uint64_tu 格式
SCNuPTRC99scanf 中用于输入 uintptr_tu 格式
SCNuMAXC99scanf 中用于输入 uintmax_tu 格式
SCNuFAST8C99scanf 中用于输入 uint_fast8_tu 格式
SCNuFAST16C99scanf 中用于输入 uint_fast16_tu 格式
SCNuFAST32C99scanf 中用于输入 uint_fast32_tu 格式
SCNuFAST64C99scanf 中用于输入 uint_fast64_tu 格式
SCNuLEAST8C99scanf 中用于输入 uint_least8_tu 格式
SCNuLEAST16C99scanf 中用于输入 uint_least816_tu 格式
SCNuLEAST32C99scanf 中用于输入 uint_least832_tu 格式
SCNuLEAST64C99scanf 中用于输入 uint_least864_tu 格式
SCNo8C99scanf 中用于输入 uint8_to 格式(有符号八进制)
SCNo16C99scanf 中用于输入 uint16_to 格式
SCNo32C99scanf 中用于输入 uint32_to 格式
SCNo64C99scanf 中用于输入 uint64_to 格式
SCNoPTRC99scanf 中用于输入 uintptr_to 格式
SCNoMAXC99scanf 中用于输入 uintmax_to 格式
SCNoFAST8C99scanf 中用于输入 uint_fast8_to 格式
SCNoFAST16C99scanf 中用于输入 uint_fast16_to 格式
SCNoFAST32C99scanf 中用于输入 uint_fast32_to 格式
SCNoFAST64C99scanf 中用于输入 uint_fast64_to 格式
SCNoLEAST8C99scanf 中用于输入 uint_least8_to 格式
SCNoLEAST16C99scanf 中用于输入 uint_least816_to 格式
SCNoLEAST32C99scanf 中用于输入 uint_least832_to 格式
SCNoLEAST64C99scanf 中用于输入 uint_least864_to 格式
SCNx8C99scanf 中用于输入 uint8_tx 格式(有符号十六进制,小写)
SCNx16C99scanf 中用于输入 uint16_tx 格式
SCNx32C99scanf 中用于输入 uint32_tx 格式
SCNx64C99scanf 中用于输入 uint64_tx 格式
SCNxPTRC99scanf 中用于输入 uintptr_tx 格式
SCNxMAXC99scanf 中用于输入 uintmax_tx 格式
SCNxFAST8C99scanf 中用于输入 uint_fast8_tx 格式
SCNxFAST16C99scanf 中用于输入 uint_fast16_tx 格式
SCNxFAST32C99scanf 中用于输入 uint_fast32_tx 格式
SCNxFAST64C99scanf 中用于输入 uint_fast64_tx 格式
SCNxLEAST8C99scanf 中用于输入 uint_least8_tx 格式
SCNxLEAST16C99scanf 中用于输入 uint_least816_tx 格式
SCNxLEAST32C99scanf 中用于输入 uint_least832_tx 格式
SCNxLEAST64C99scanf 中用于输入 uint_least864_tx 格式

创建于 2025/6/30

更新于 2025/6/30