printf和scanf
一、printf
函数 - 格式化输出
1. 基本语法
#include <stdio.h>int printf(const char *format, ...);
- 功能:按照指定格式向标准输出(通常是屏幕)打印数据
- 返回值:成功返回输出的字符数,失败返回负数
2. 格式控制字符串
格式控制字符串由普通字符和格式说明符组成:
printf("普通字符 %格式说明符", 变量);
常见的格式说明符:
格式符 | 描述 | 示例 |
---|---|---|
%d | 十进制整数 | printf("%d", 10); |
%u | 无符号十进制整数 | printf("%u", 10); |
%f | 浮点数 | printf("%f", 3.14); |
%s | 字符串 | printf("%s", "Hi"); |
%c | 字符 | printf("%c", 'A'); |
%x | 十六进制整数(小写) | printf("%x", 255); |
%X | 十六进制整数(大写) | printf("%X", 255); |
%p | 指针地址 | printf("%p", &num); |
%% | 打印百分号本身 | printf("%%"); |
3. 格式化选项
可以在%
和格式符之间添加额外选项:
%[标志][宽度][.精度][长度]类型
-
标志:
-
:左对齐(默认右对齐)+
:强制显示正负号0
:数字前补零空格
:正数前加空格
-
宽度和精度:
printf("%5d", 123); // 宽度为5,右对齐:" 123" printf("%-5d", 123); // 左对齐:"123 " printf("%.2f", 3.1415); // 保留2位小数:"3.14" printf("%8.2f", 3.1415); // 总宽度8,小数2位:" 3.14"
-
long num = 1234567890L; printf("%ld", num); // 使用%ld输出long类型
4. 示例代码
#include <stdio.h>int main() {int num = 100;float f = 3.14159;char str[] = "Hello";// 基本输出printf("整数: %d\n", num);printf("浮点数: %f\n", f);printf("字符串: %s\n", str);// 格式化输出printf("宽度控制: |%10d|\n", num); // 宽度10,右对齐printf("左对齐: |%-10d|\n", num); // 左对齐printf("补零: |%010d|\n", num); // 补零printf("浮点数精度: %.2f\n", f); // 保留2位小数printf("组合控制: |%+010.2f|\n", -f); // 带符号、补零、宽度10、2位小数return 0;
}
二、scanf
函数 - 格式化输入
1. 基本语法
#include <stdio.h>int scanf(const char *format, ...);
- 功能:从标准输入(通常是键盘)读取数据并按格式存储到变量中
- 返回值:成功匹配并赋值的变量个数,失败返回 EOF(通常为 - 1)
2. 格式控制字符串
与printf
类似,但用于解析输入:
scanf("%格式说明符", &变量地址);
常见的格式说明符:
格式符 | 描述 | 示例 |
---|---|---|
%d | 读取十进制整数 | scanf("%d", &num); |
%f | 读取浮点数 | scanf("%f", &f); |
%s | 读取字符串(遇空格停止) | scanf("%s", str); |
%c | 读取单个字符 | scanf("%c", &ch); |
%[ ] | 读取指定字符集 | scanf("%[0-9]", str); |
3. 使用注意事项
-
变量地址:必须使用
&
取地址符(字符串数组除外)int num; scanf("%d", &num); // 正确:传递变量地址char str[20]; scanf("%s", str); // 正确:数组名本身就是地址
-
空白字符处理:
scanf
默认会跳过空白字符(空格、制表符、换行符)- 读取字符时需特别注意:
char ch1, ch2; scanf("%c", &ch1); // 读取第一个字符 scanf(" %c", &ch2); // 加空格跳过前面的空白字符
-
字符串读取限制:
- 使用
%s
读取字符串时存在缓冲区溢出风险 - 建议指定最大宽度:
char str[10]; scanf("%9s", str); // 最多读取9个字符,留一个位置给'\0'
- 使用
4. 示例代码
#include <stdio.h>int main() {int num;float f;char ch;char str[20];// 读取整数printf("请输入一个整数: ");scanf("%d", &num);printf("你输入的整数是: %d\n", num);// 读取浮点数printf("请输入一个浮点数: ");scanf("%f", &f);printf("你输入的浮点数是: %f\n", f);// 读取字符(注意空白字符)printf("请输入一个字符: ");scanf(" %c", &ch); // 前面的空格跳过空白字符printf("你输入的字符是: %c\n", ch);// 读取字符串printf("请输入一个单词: ");scanf("%19s", str); // 限制最大长度防止溢出printf("你输入的单词是: %s\n", str);return 0;
}
三、printf
与scanf
的高级用法
1. 多变量输入输出
int a, b;
printf("请输入两个整数: ");
scanf("%d %d", &a, &b); // 用空格分隔输入
printf("两数之和: %d\n", a + b);
2. 自定义输入格式
int year, month, day;
printf("请输入日期(YYYY-MM-DD): ");
scanf("%d-%d-%d", &year, &month, &day);
printf("你输入的日期是: %d年%d月%d日\n", year, month, day);
3. 错误处理
检查scanf
的返回值:
int num;
printf("请输入一个整数: ");
if (scanf("%d", &num) != 1) {printf("输入错误!请输入一个整数。\n");// 清除输入缓冲区while (getchar() != '\n');
}
四、常见问题与技巧
1. 输入缓冲区问题
scanf
读取输入后,缓冲区可能残留换行符- 解决方法:
// 清除输入缓冲区 while (getchar() != '\n');
2. 读取带空格的字符串
使用%[^\n]
读取整行:
char str[100];
printf("请输入一行文字: ");
scanf(" %[^\n]", str); // 跳过空白,读取直到换行符
printf("你输入的是: %s\n", str);
3. 读取单个字符
确保跳过前面的空白字符:
char ch;
scanf(" %c", &ch); // 空格跳过空白字符