目录
一、printf( ) 函数详解
1. 基本用法
printf( )
的作用是将参数文本输出到屏幕。它名字里面的 f
代表 format
(格式化),表示可以
定制输出文本的格式。
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
运行结果:
Hello World
printf( )
函数原型:
参数1: format 是一个字符串,他的内容就是显示到屏幕终端的内容。其中占位符的内容会被后面的参数给替代。
参数2:可以有若干个,用来替换前面的占位符。
printf( )
是在标准库的头⽂件 stdio.h
定义的。使用这个函数之前,必须在源码文件头部引入这个头文件。
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
后面没有换行符\n
不会进行换行,如果我们想要换行,就需要\n
。
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
2.占位符
printf( )
可以在输出文本中指定占位符。
所谓占位符,就是这个位置可以用其他值代入。
#include <stdio.h>
int main()
{
printf("There are %d apples\n", 3);
return 0;
}
// 输出 There are 3 apples
上面示例中, There are %d apples\n
是输出文本,里面的 %d
就是占位符,表示这个位置要用其他值来替换。占位符的第⼀个字符⼀律为百分号%
,第⼆个字符表示占位符的类型, %d
表示这里代入的值必须是⼀个整数。
printf( )
的第二个参数就是替换占位符的值,上⾯的例子是整数3
替换 %d
。
执行后的输出结果就是 There are 3 apples
。
当然,输出文本里也可以同时使用多个占位符。
#include <stdio.h>
int main()
{
printf("%s says it is %d o'clock\n", "lisi", 21);
return 0;
}
运行结果:
lisi says it is 21 o’clock
%s
是表示代入的是一个字符串。
printf( )
参数与占位符是⼀ 对应关系,如果有 n
个占位符, printf( )
的参数就应该有 n + 1
个。如果参数个数少于对应的占位符,printf( )
可能会输出内存中的任意值。
例如:
#include <stdio.h>
int main()
{
printf("%s says it is %d o'clock\n", "lisi");
return 0;
}
运行结果:
lisi says it is -597291232 o’clock
3.占位符列举
• %a :⼗六进制浮点数,字⺟输出为⼩写。
• %A :⼗六进制浮点数,字⺟输出为⼤写。
• %c :字符。//char
• %d :⼗进制整数。//int
• %e :使⽤科学计数法的浮点数,指数部分的 e 为⼩写。
• %E :使⽤科学计数法的浮点数,指数部分的 E 为⼤写。
• %i :整数,基本等同于 %d 。
• %f :⼩数(包含 float 类型和 double 类型)。//float--%f double--%lf
• %g :6个有效数字的浮点数。整数部分一旦超过6位,就会⾃动转为科学计数法,指数部分的 e 为⼩写。
• %G :等同于 %g ,唯⼀的区别是指数部分的 E 为⼤写。
• %hd :⼗进制short int类型。
• %ho :⼋进制short int类型。
• %hx :⼗六进制short int类型。
• %hu :unsigned short int类型。
• %ld :⼗进制long int类型。
• %lo :⼋进制long int类型。
• %lx :⼗六进制long int类型。
• %lu :unsigned long int类型。
• %lld :⼗进制long long int类型。
• %llo :⼋进制long long int类型。
• %llx :⼗六进制long long int类型。
• %llu :unsigned long long int类型。
• %Le :科学计数法表⽰的long double类型浮点数。
• %Lf :long double类型浮点数。
• %n :已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中。
• %o :⼋进制整数。
• %p :指针(⽤来打印地址)。
• %s :字符串。
• %u :⽆符号整数(unsigned int)。
• %x :⼗六进制整数。
• %zd : size_t 类型。
• %% :输出一个百分号。
4.printf()的返回值
- 成功输出时:
printf( )
返回输出的字符数量
包括:
- 所有普通字符(如字母、数字、标点)
- 转义字符
- 格式字符串中的非占位符内容
例如:
printf("a%db", 123); // 输出"a123b",返回值5(a+3位数字+b)
经典示例:
#include <stdio.h>
int main()
{
int r = 0;
r = printf("%d\n", printf("%d", printf("%d", 43)));
printf("r = %d\n", r);
return 0;
}
printf("%d", 43) ---> 返回值:2
printf("%d", printf("%d", 43)) ---> 返回值:1
printf("%d", printf("%d", printf("%d", 43))) ---> 返回值:2
\n
—> 换行符也是字符,也会被统计在printf( )
的返回值中。
二. 输出格式
printf( )
可以定制占位符的输出格式。
1. 限定宽度
printf( )
允许限定占位符的最小宽度。
#include <stdio.h>int main()
{
printf("%10d\n", 123);
return 0;
}
// 输出为 " 123"
上⾯示例中, %10d
表⽰这个占位符的宽度⾄少为10
位。如果不满10
位,对应的值的前面会添加空格。
输出的值默认是右对齐,即输出内容前面会有空格;如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的 %
的后⾯插⼊⼀个 -
号。
#include <stdio.h>int main()
{
printf("%-10d\n", 123);
return 0;
}
// 输出为 "123 "
对于小数,这个限定符会限制所有数字的最小显示宽度。
#include <stdio.h>int main()
{
printf("%15lf\n", 12.3);
return 0;
}
// 输出为 " 12.300000"
#include <stdio.h>int main()
{
printf("%-15lf\n", 12.3);
return 0;
}
// 输出为 "12.300000 "
2. 限定小数位数
输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留两位,占位符可以写
成 %.2f
。
#include <stdio.h>int main()
{
printf("%.2f\n", 12.3);
return 0;
}
// 输出为 "12.30"
还有一种特别的写法:
最小宽度和小数位数这两个限定值,都可以⽤*
代替,通过 printf( )
的参数传入。
#include <stdio.h>
int main()
{
printf("%*.*f\n", 6, 2, 0.5);
return 0;
}
// 等同于printf("%6.2f\n", 0.5);
//输出为 " 0.50"
上⾯示例中, %* . *f
的两个星号通过 printf( )
的两个参数 6
和 2
传入。
3. 输出部分字符串
%s
占位符⽤来输出字符串,默认是全部输出。如果只想输出开头的部分,可以用 %.[m]s
指定输出
的⻓度,其中 [m]
代表⼀个数字,表示所要输出的长度。
#include <stdio.h>
int main()
{
printf("%.5s\n", "hello world");
return 0;
}
// 输出 hello
//表示只输出前五个字符
三、scanf( ) 函数详解
1. 基本用法
scanf( )
函数用于读取用户的键盘输⼊。
程序运行到这个语句时,会停下来,等待用户从键盘输⼊。
用户输入数据、按下回车键后, scanf( )
就会处理用户的输入,将其存入变量。
它的原型定义在头⽂件 stdio.h
。scanf( )
的语法跟 printf( )
类似。
#include <stdio.h>
int main()
{
int score = 0;
printf("请输⼊成绩:");
scanf("%d", &score);
printf("成绩是:%d\n", score);
return 0;
}
1. scanf("%d", &i);
它的第⼀个参数是⼀个格式字符串,里面会放置占位符(与 printf( )
的占位符基本⼀致),告诉编
译器如何解读用户的输⼊,需要提取的数据是什么类型。
这是因为 C 语⾔的数据都是有类型的, scanf( )
必须提前知道用户输⼊的数据类型,才能处理数
据。
它的其余参数就是存放用户输⼊的变量,格式字符串里面有多少个占位符,就有多少个变量。
int i;
int j;
float x;
double y;
scanf("%d%d%f%f", &i, &j, &x, &y);
scanf( )
处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符等。
scanf( )
处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存
进行解读。
如:
#include <stdio.h>
int main()
{
int x;
float y;
// ⽤⼾输⼊ " -13.45e12# 0"
scanf("%d", &x);
printf("%d\n", x);
scanf("%f", &y);
printf("%lf\n", y);
return 0;
}
2.占位符
scanf( )
常⽤的占位符如下,与printf( )
的占位符基本⼀致。
• %c :字符。
• %d :整数。
• %f : float 类型浮点数。
• %lf : double 类型浮点数。
• %Lf : long double 类型浮点数。
• %s :字符串。
• %[] :在⽅括号中指定⼀组匹配的字符(⽐如 %[0-9] ),遇到不在集合之中的字符,匹配将会停⽌。
上⾯所有占位符之中,除了 %c
以外,都会自动忽略起首的空白字符。 %c
不忽略空白字符,总是返回当前第⼀个字符,无论该字符是否为空格。
如果要强制跳过字符前的空白字符,可以写成 scanf(" %c", &ch)
,即 %c
前加上⼀个空格,表示跳过零个或多个空白字符。
• %[] :在⽅括号中指定⼀组匹配的字符(⽐如 %[0-9] ),遇到不在集合之中的字符,匹配将会停⽌。
#include <stdio.h>
int main()
{
char str[100];
printf("请输入字母和数字(遇到非字母数字停止):");
scanf("%[a-zA-Z0-9]", str); // 只读取字母和数字
printf("读取的内容:%s\n", str);
return 0;
}
注意⚠️:
还有一个经常用到的是%[^\n]
是用来读取整行(直到换行符停止)“Hello\n” → “Hello” 。
int main()
{
char arr[100];
scanf("%[^\n]", arr);
printf("%s", arr);
return 0;
}
3.scanf( )的返回值
scanf
函数的返回值是成功赋值给变量的参数个数。例如:
int a, b;
int result = scanf("%d %d", &a, &b);
- 若输入两个整数(如
12 34
),result 为2
。 - 若输入一个整数后遇到非数字字符(如
12 abc
),result 为1
。 - 若输入完全不匹配(如
abc
),result 为0
。 - 若遇到文件结束符(如
Ctrl+Z
(Windows)或Ctrl+D
(Linux)),返回EOF
(通常为-1
)。
在VS2022上,需要连续三个Ctrl+Z
(Windows)才会感应到文件结束符。
3.1 返回值的用途:
- 输入有效性验证
通过判断返回值是否等于预期参数个数,确保输入数据合法:
#include <stdio.h>
int main()
{
int num = 0;
if (scanf("%d", &num) != 1)
{
printf("输入错误");
// 清空输入缓冲区
while (getchar() != '\n');
}
return 0;
}
- 循环读取输入
结合EOF
实现持续读取输入直到结束,例如处理多组测试数据:
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
while (scanf("%d %d", &a, &b) != EOF)
{
if (a == 0 && b == 0)
break;
printf("%d\n", a + b);
}
return 0;
}
- 避免未初始化变量的风险
若返回值小于预期,说明部分变量未成功赋值,此时应避免使用这些变量。
3.2 注意事项: - 输入缓冲区残留问题
当scanf
因格式不匹配中断时,残留数据可能导致后续输入错误。需手动清空缓冲区:
int c;
while ((c = getchar()) != '\n' && c != EOF); // 清空缓冲区
- 安全性与编译器警告
Visual Studio 等编译器可能因安全性问题提示scanf
警告,可改用scanf_s
或添加宏定义
:
#define _CRT_SECURE_NO_WARNINGS // 禁用警告