C语言scanf()函数的用法(非常详细)
在 C语言中,scanf() 函数是一个标准库函数,用于读取各种类型的数据,如整数、浮点数、字符、字符串等,它可以读取不同类型的数据。
下面是一个最简单的示例,它使用 scanf() 函数从键盘中获取用户输入的各种数据:
程序的运行结果为:
如果你使用较新版本的 Visual Studio,则 scanf() 这类函数会被认为是不安全的,编译器会抛出 C4996 错误,并建议你使用其他安全函数替代。
C4996 是 Visual Studio 编译器的警告信息之一,表示使用了已被标记为不安全或已过时的函数。报错信息如下图所示:

图 1 C4996 报错
要解决 C4996 错误,我们提供过一个解决办法,大家可以猛击《VS安全函数问题(C语言安全函数)是怎么回事?如何解决?》一文详细了解,这里不再过多赘述。

图 2 scanf()函数第一个参数为字符串

图 3 scanf() 函数的第一个参数是需要输入的字符串以及转换规范
转换规范用于指定输入的数据类型和变量类型。例如,"%d" 表示要读取一个整数,"%f" 表示要读取一个浮点数。

图 4 scanf() 函数的后续参数是转换完成后数据的存放位置
这些变量的类型必须与转换规范指定的类型相匹配。例如:
在使用 scanf() 函数时,& 被添加到变量名之前。这里暂时不探究 & 的含义,只需记住以下两条规则:

图 5 转换规范的类型和数量与后续的参数一一对应
下图直观地展示了输入数据与转换规范的对应关系。

图 6 字符与转换规范匹配
例如,数据 "1" 对应转换规范 "%hhd";数据 "2" 对应转换规范 "%hd";数据 "3" 对应转换规范 "%d";数据 "4" 对应转换规范 "%ld";数据 "5.6" 对应转换规范 "%f";数据 "7.8" 对应转换规范 "%lf"。
需要特别注意的是,用户在输入时必须按照第一个字符串的形式进行输入,否则无法得到正确的结果。接下来,我们举三个例子来说明这一点。
总而言之,scanf() 函数会将输入的数据与第一个参数进行匹配,从而找到需要转换的部分。如果字符串匹配失败,将无法得到正确的转换结果。因此,在编写 scanf() 函数时,务必确保输入数据与转换规范的格式相匹配,这样才能获得正确的输出结果。
对于scanf() 函数的匹配规则,初学者经常会犯一些错误。下面是一些常见的错误和解决方法。
例如,下面的代码就是错误的用法。
下面是一个正确的例子:
有些初学者可能会习惯性地在 scanf() 函数的匹配字符串中添加一些无用的字符,例如下面的代码:
下面是一个最简单的示例,它使用 scanf() 函数从键盘中获取用户输入的各种数据:
#include <stdio.h> int main() { char c; short s; int n; long l; float f; double df; scanf("%hhd %hd %d %ld %f %lf", &c, &s, &n, &l, &f, &df); printf("获取的数据如下:%d %d %d %ld %f %f\n", c, s, n, l, f, df); return 0; }运行程序后,用户需要输入数据,如 1、2、3、4、5.6、7.8,并按 Enter 键。scanf() 函数会读取这些数据,并将其存储到对应的变量中。然后,printf() 函数将这些变量的值输出到屏幕上。
程序的运行结果为:
1 2 3 4 5.6 7.8
获取的数据如下:1 2 3 4 5.600000 7.800000
Visual Studio安全报错
在讲解 scanf() 函数之前,我们需要了解 Visual Studio 中与 scanf() 相关的安全报错。如果你使用较新版本的 Visual Studio,则 scanf() 这类函数会被认为是不安全的,编译器会抛出 C4996 错误,并建议你使用其他安全函数替代。
C4996 是 Visual Studio 编译器的警告信息之一,表示使用了已被标记为不安全或已过时的函数。报错信息如下图所示:

图 1 C4996 报错
要解决 C4996 错误,我们提供过一个解决办法,大家可以猛击《VS安全函数问题(C语言安全函数)是怎么回事?如何解决?》一文详细了解,这里不再过多赘述。
scanf()函数的使用
scanf() 函数与 printf() 函数的使用方法也有很多相似之处,下面详细分析 scanf() 的用法。1) scanf()是一个变参函数
和 printf() 函数一样,scanf() 函数也是一个变参函数,可以接收不确定数量和类型的参数。这使得 scanf() 函数非常灵活,可以用于读取各种不同类型的输入数据。2) scanf()函数的第一个参数为字符串
scanf() 函数的第一个参数为字符串(见下图),该字符串用于匹配输入的字符。
图 2 scanf()函数第一个参数为字符串
3) scanf()函数的第一个参数包含匹配字符以及转换规范
scanf函数的第一个参数包含匹配字符以及转换规范(见下图),它们一起决定了要读取的数据类型。匹配字符用于指定输入的格式,包括空格、逗号等。
图 3 scanf() 函数的第一个参数是需要输入的字符串以及转换规范
转换规范用于指定输入的数据类型和变量类型。例如,"%d" 表示要读取一个整数,"%f" 表示要读取一个浮点数。
4) scanf()函数的后续参数是转换完成后数据的存放位置
查看下图,scanf() 函数将根据相应的转换规范对输入的字符串进行转换,并将其按顺序存储在后续参数的变量中。
图 4 scanf() 函数的后续参数是转换完成后数据的存放位置
这些变量的类型必须与转换规范指定的类型相匹配。例如:
- %hhd 匹配 char 类型的数据,然后将其保存在 char 类型的变量 c 中;
- %hd 匹配 short 类型的数据,然后将其保存在 short 类型的变量 s 中;
- %d 匹配 int 类型的数据,然后将其保存在 int 类型的变量 n 中;
- %ld 匹配 long 类型的数据,然后将其保存在 long 类型的变量 l 中;
- %f 匹配 float 类型的数据,然后将其保存在 float 类型的变量 f 中;
- %lf 匹配 double 类型的数据,然后将其保存在 double 类型的变量 df 中。
在使用 scanf() 函数时,& 被添加到变量名之前。这里暂时不探究 & 的含义,只需记住以下两条规则:
- 如果 scanf() 函数将转换后的数据存储到基本数据类型的变量当中,则在变量名前添加 &;
- 如果 scanf() 函数将字符串存储到字符数组中,则在字符数组名前不用添加 &。
5) 转换规范的类型和数量与后续的参数一一对应
查看下图,转换规范的类型和数量必须与后续的参数一一对应。这意味着每个转换规范都必须有一个对应的变量来接收转换后的数据。
图 5 转换规范的类型和数量与后续的参数一一对应
scanf()函数的匹配规则
在 C 语言中,scanf() 函数用于读取用户从键盘上输入的数据。scanf() 函数会将输入的数据与第一个参数的字符串进行匹配,找到输入数据与转换规范的一一对应关系。下图直观地展示了输入数据与转换规范的对应关系。

图 6 字符与转换规范匹配
例如,数据 "1" 对应转换规范 "%hhd";数据 "2" 对应转换规范 "%hd";数据 "3" 对应转换规范 "%d";数据 "4" 对应转换规范 "%ld";数据 "5.6" 对应转换规范 "%f";数据 "7.8" 对应转换规范 "%lf"。
需要特别注意的是,用户在输入时必须按照第一个字符串的形式进行输入,否则无法得到正确的结果。接下来,我们举三个例子来说明这一点。
- 例子 1:假设 scanf() 函数的第一个字符串为 "%hhd %hd %d %ld %f %lf",它的每个转换规范使用空格进行分隔。因此,相应地,用户在输入数据时也必须用空格对数据进行分隔,如 "1 2 3 4 5.6 7.8"。
- 例子 2:假设 scanf() 函数的第一个字符串为 "%hhd,%hd,%d,%ld,%f,%lf",它的每个转换规范使用逗号进行分隔。因此,相应地,用户在输入数据时也必须用逗号对数据进行分隔,如 "1,2,3,4,5.6,7.8"。
- 例子 3:假设 scanf() 函数的第一个字符串为 "%hhd+%hd-%dx%ld/%f~%lf",它的转换规范使用加号、减号、乘号、除号和波浪号进行分隔。因此,相应地,用户在输入数据时也必须使用这些分隔符号对数据进行分隔,如 "1+2-3×4/5.6~7.8"。
总而言之,scanf() 函数会将输入的数据与第一个参数进行匹配,从而找到需要转换的部分。如果字符串匹配失败,将无法得到正确的转换结果。因此,在编写 scanf() 函数时,务必确保输入数据与转换规范的格式相匹配,这样才能获得正确的输出结果。
对于scanf() 函数的匹配规则,初学者经常会犯一些错误。下面是一些常见的错误和解决方法。
1) 把scanf()函数当作printf()函数使用
需要明确一点,scanf() 是一个输入函数,而 printf() 是一个输出函数。它们的功能正好相反。有些初学者可能会混淆它们之间的区别,导致在使用 scanf() 函数时出现错误。例如,下面的代码就是错误的用法。
int n; scanf("请输入一个整数:%d",&n); printf("%d", n);在运行这段代码后,控制台不会显示提示文字“请输入一个整数:”。输入一个整数后,控制台可能会输出一个无意义的数字:
6
-858993460
下面是一个正确的例子:
int n; printf("请输入一个整数:"); scanf("%d",&n); printf("%d", n);运行结果为:
请输入一个整数:6
6
2) 添加一些无用字符
scanf() 函数的第一个参数应该包含匹配字符和转换规范,不需要添加其他额外的内容。有些初学者可能会习惯性地在 scanf() 函数的匹配字符串中添加一些无用的字符,例如下面的代码:
int a,b,c; scanf("%d %d %d\n",&a,&b,&c);其中,\n 是换行符,我们通常在 printf() 函数中使用它来进行换行操作。但是,如果将 \n 添加到 scanf() 函数的匹配字符串中,则在输入数据时需要按两次 Enter 键(为了让 scanf() 成功匹配 \n,还需要最后额外输入一个任意字符)。因此,应该避免在 scanf() 函数的匹配字符串中添加无用的字符,只包含匹配字符和转换规范即可。