C 格式化输入输出与字符读写
将格式化的数据发送到标准输出设备 语法:int printf(const char format, ...); 参数: format:格式化字符串,指定输出的格式。 ...:可变参数列表,根据格式化字符串中的格式说明符,提供要输出的数据。 printf() 可以在输出文本中指定占位符 占位符的含义指的是:这个位置可以用其他的值代入 C printf("%s will be better","tomorrow");
printf()
- 将格式化的数据发送到标准输出设备
语法:
int printf(const char *format, ...);参数: - format:格式化字符串,指定输出的格式。
...:可变参数列表,根据格式化字符串中的格式说明符,提供要输出的数据。
printf 的占位符
printf() 可以在输出文本中指定占位符 占位符的含义指的是:这个位置可以用其他的值代入
EXAMPLE
printf("%s will be better","tomorrow");
占位符的第1个字符一律用百分号%,第2个字符表示占位符的类型 %d表示这里代入的值必须是一个整数。
在文本中使用占位符的数量没有限制
占位符汇总
ABSTRACT: ⚡ 高频常用速查 (The “Big Five”) 日常开发中 90% 的情况只需要用到这五个:
%d➔ 十进制整数 (int)%f➔ 浮点小数 (float/double)%c➔ 单个字符 (char)%s➔ 字符串 (char*)%p➔ 指针/内存地址
🔢 1. 整数家族 (Integer)
| 占位符 | 对应数据类型 | 格式与显示说明 |
|---|---|---|
%d / %i |
int |
有符号十进制(两者在 printf 中用法一致) |
%u |
unsigned int |
无符号十进制 |
%o |
int |
八进制(输出不带 0 前缀) |
%x |
int |
十六进制(字母小写,如 1a) |
%X |
int |
十六进制(字母大写,如 1A) |
%hd |
short int |
短整型(有符号) |
%hu |
unsigned short |
短整型(无符号) |
%ld |
long int |
长整型(有符号) |
%lu |
unsigned long |
长整型(无符号) |
%lld |
long long int |
超长整型(有符号) |
%llu |
unsigned long long |
超长整型(无符号) |
%zd |
size_t |
专用于输出 sizeof() 的结果 |
📊 2. 浮点数家族 (Floating Point)
| 占位符 | 对应数据类型 | 格式与显示说明 |
|---|---|---|
%f |
float / double |
标准小数(默认保留 6 位小数) |
%Lf |
long double |
长双精度小数 |
%e |
float / double |
科学计数法(指数带小写 e) |
%E |
float / double |
科学计数法(指数带大写 E) |
%g |
float / double |
智能适配(自动在 %f 和 %e 中选择较短的,最多 6 位有效数字,小写 e) |
%G |
float / double |
智能适配(同上,但使用大写 E) |
%a |
float / double |
十六进制浮点(P 计数法,小写字母,C99 标准) |
%A |
float / double |
十六进制浮点(P 计数法,大写字母,C99 标准) |
🔤 3. 字符与字符串 (Character & String)
| 占位符 | 对应数据类型 | 格式与显示说明 |
|---|---|---|
%c |
char |
输出单个字符 |
%s |
char* (字符数组/指针) |
输出字符串(直到遇到结束符 \0 为止) |
🛠️ 4. 特殊功能 (Special)
| 占位符 | 功能描述 | 注意事项 |
|---|---|---|
%p |
打印指针地址 | 通常以十六进制显示,并自动带 0x 前缀(因编译器而异) |
%n |
统计输出字符数 | ⚠️ 此符号不输出任何内容! 它会将当前已打印的字符总数,赋值给传入的 int* 指针变量 |
| **`:输出一个百分号 |
## 定制占位符的输出格式
### 限定宽度
_限定占位符的**最小宽度。**_
```C
#include <stdio.h>
int main()
{
printf("%5d\n",123);
return 0;
}
//结果为“ 123”(前面空两格)
%5d 表示这个占位符的宽度至少是5位。如果不满5位,对应的值在前面会添加空格。输出的值 默认是右对齐,即输出内容前面会有空格,如果希望改为左对齐,在输出内容后面添加空格。可以在占位符的百分号的后面插入一个 - 号。
总是显示正负号
让正数也输出+号,可以在占位符的%后面加一个+
#include <stdio.h>
int main()
{
printf("%+d\n",12);//输出 +12
printf("%+d\n",-12);//输出 -12
return 0;
}
限定小数位数
举例来说,希望小数点后面只保留两位,占位符可以写成 %.2f
#include <stdio.h>
int main()
{
printf("Number is %.2f\n",0.5);
return 0;
}
//结果输出为:Number is 0.50
与限定宽度展位符混用
#include <stdio.h>
int main()
{
printf("%6.2f\n", 0.5);
return 0;
}
//输出结果为:“ 0.50”
上面示例中,%6.2f 表示输出字符串最小宽度为6,小数位数为2。所以,输出字符串的头部有两个空格。
最小宽度和小数位数这两个限定值,都可以用*代替,通过printf()的参数传入
#include <stdio.h>
int main()
{
printf("%*.*f\n",6,2,0.5);//等同于printf("%6.2f\n",0.5);
return 0;
}
上面示例中,%*.*f 的两个星号通过printf()的两个参数6和2传入
输出部分字符串
scanf()
语法:int scanf(const char *format, ...);
参数:
format:格式化字符串,指定输入的格式。...:可变参数列表,根据格式化字符串中的格式说明符,提供存储输入数据的变量地址。
Tip: 延伸阅读 标准输入输出掌握后,可以继续看 c-file-operations,理解
stdin/stdout与文件流读写的关系。
一般格式:
scanf(格式控制,地址列表)
格式控制字符串
基础转换说明符 (Conversion Specifiers)
这些符号告诉编译器:“我要读入什么类型的数据?”
| 符号 | 对应的变量类型 | 说明 |
|---|---|---|
%d |
int |
有符号十进制整数 |
%f |
float |
单精度浮点数 |
%lf |
double |
双精度浮点数(注意: scanf 必须加 l) |
%c |
char |
单个字符(包括空格、换行符) |
%s |
char[] (字符串) |
字符串,读取到空格、制表符或换行符处停止 |
%u |
unsigned int |
无符号十进制整数 |
%x / %X |
int |
十六进制整数 |
%o |
int |
八进制整数 |
%p |
void* |
指针(地址值) |
长度修饰符 (Length Modifiers)
用于匹配特定位宽的整数或浮点数。
-
h: 短整型。例如%hd用于short。 -
l: 长类型。例如%ld用于long,%lf用于double。 -
ll: 超长整型。例如%lld用于long long。 -
L: 长双精度。例如%Lf用于long double。
特殊格式控制语法
域宽 (Width)
在 % 和说明符之间加上数字,限制读取的最大字符数。
示例:
scanf("%5d", &num);—— 最多读取 5 位数字。如果输入1234567,num只会得到12345。
赋值抑制符 (*)
表示读取该项但不保存到任何变量中,直接跳过。
示例:
scanf("%d %*d %d", &a, &b);—— 如果输入10 20 30,a得到10,20被跳过,b得到30。
扫描集 (Scan Set) [ ]
用于匹配特定的字符集。
-
%[a-z]:只读取小写字母。 -
%[^0-9]:读取除数字以外的所有字符(^表示取反)。
常见的“坑”与注意事项
-
取地址符
&:除了字符串数组名(%s)本身就是地址外,其他变量必须加&。 -
空格问题:
-
%c会读取任何字符,包括你上次输入留下的回车符(\n)。建议写成" %c"(前面加个空格),可以跳过前面的所有空白符。 -
除了
%c和%[],其他说明符都会自动跳过前面的空格、制表符和换行符。
-
-
非格式字符:
- 如果你写
scanf("age=%d", &a);,那么你在键盘上必须精准输入age=18才能读取成功。
- 如果你写
-
不要在格式字符串中加\n,在使用scanf时,格式控制应该尽量的简单
参数
规定符
- %d 十进制有符号整数
- %u 十进制无符号整数
- %f 浮点数
- %s 字符串
- %c 单个字符
- %p 指针的值
- %e 指数形式的浮点数
- %x, %X 无符号以十六进制表示的整数
- %o 无符号以八进制表示的整数
- %g 把输出的值按照 %e 或者 %f 类型中输出长度较小的方式输出
- %p 输出地址符
- %lu 32位无符号整数
- %llu 64位无符号整数
- %% 输出百分号字符本身。
除了格式化说明符之外,printf() 函数还支持一些标志和选项,用于控制输出的精度、宽度、填充字符和对齐方式等。例如:
- %-10s:左对齐并占用宽度为 10 的字符串;
- %5.2f:右对齐并占用宽度为 5,保留两位小数的浮点数;
- %#x:输出带有 0x 前缀的十六进制数。
printf() 函数也支持变长参数列表,可以使用省略号 … 来表示,用于指定要输出的多个值。
字符数据的输入输出
putchar()
<stdio.h> 头文件中的原型为:int putchar(int c);
输出一个字符
putchar() 函数接受一个 int 类型的参数,但实际上它会被转换为一个无符号字符(范围 0~255),这意味着:
- 虽然参数类型是 int,但只有低 8 位会被使用;
- 可以直接传入字符字面量,如 ‘A’;
- 可以传入 ASCII 码值,如 65(对应 ‘A’)。
putchar() 函数的返回值也是 int 类型:
- 如果字符成功输出,返回该字符的 ASCII 码值。
- 如果发生错误,返回 EOF(通常定义为 -1)。
putchar() 函数的主要作用是将一个字符写入到标准输出流中,并在调用后自动刷新缓冲区,确保字符立即显示在屏幕上。
putchar() 可以输出所有 ASCII 字符,包括不可见的控制字符。
putchar('A'); //输出A
putchar(65); //输出A
int a = putchar('A'); //a的值为65
printf("%d\n",a);
putchar('\101'); ////输出A,\101是八进制
putchar('\x41'); ////输出A,\x41是十六进制
getchar()
<stdio.h> 头文件中的原型为:int getchar(void);
输入一个字符
从原型可以看出,getchar() 不接受任何参数,返回值类型为 int
尽管 getchar() 用于读取字符,但它的返回值类型是 int 而不是 char。这是因为 getchar() 需要能够表示所有可能的字符值(0 到 255)以及一个额外的值 EOF(通常定义为 -1)来表示输入结束。
- 如果成功读取到字符,getchar() 返回该字符的 ASCII 值。
- 如果到达文件末尾或发生读取错误,getchar() 返回 EOF。
int ch
ch = getchar(); //读取单个字符
int ch
while ((ch = getchar()) != '\n' && ch != EOF) {
putchar(ch); //读取多个字符直到遇到换行符
}
int age;
char name[50];
printf("请输入你的年龄:");
scanf("%d", &age);
// 清除输入缓冲区中的换行符
while (getchar() != '\n');
printf("请输入你的名字:");
fgets(name, sizeof(name), stdin);
printf("你好,%s你的年龄是 %d 岁。\n", name, age);
return 0;