【09】C语言中的格式输入函数scanf()详解
文章目录
- [1. 基本用法](#1. 基本用法)
- [2. 格式说明符详解](#2. 格式说明符详解)
- [3. 高级用法](#3. 高级用法)
-
- [3.1 宽度限定符](#3.1 宽度限定符)
- [3.2 跳过某些输入](#3.2 跳过某些输入)
- [3.3 扫描集](#3.3 扫描集)
- [4. 常见问题与注意事项](#4. 常见问题与注意事项)
-
- [4.1 缓冲区问题](#4.1 缓冲区问题)
- [4.2 字符串输入限制](#4.2 字符串输入限制)
- [4.3 输入验证](#4.3 输入验证)
- [4.4 综合代码示例](#4.4 综合代码示例)
scanf()是C语言标准库中最常用的输入函数之一,它允许从标准输入(通常是键盘)按照指定格式读取数据。下面我将全面讲解这个函数的使用方法和注意事项。
1. 基本用法
基本语法
c
int scanf(const char *format, ...);
- 返回值:成功读取的数据项个数,如果失败则返回EOF(通常是-1)
- format参数:格式控制字符串,指定输入数据的格式
- ...:可变参数列表,是需要读取的变量地址
要点须知:
- 始终检查返回值:确保所有预期的数据都被成功读取
- 注意缓冲区问题:特别是混合使用不同格式说明符时
- 限制输入长度:防止缓冲区溢出,尤其是字符串输入
- 考虑使用更安全的替代方案 :如
fgets()+sscanf() - 处理无效输入:提供错误恢复机制
代码示例
c
#include <stdio.h>
int main() {
// 设置控制台为GBK编码(Windows中文默认编码)
SetConsoleOutputCP(936);
int age;
float height;
char name[50];
printf("请输入您的年龄、身高和姓名:");
scanf("%d %f %s", &age, &height, name);
printf("年龄:%d,身高:%.2f,姓名:%s\n", age, height, name);
return 0;
}
执行效果:
请输入您的年龄、身高和姓名:18 180.5 frank
年龄:18,身高:180.50,姓名:frank
2. 格式说明符详解
| 格式符 | 说明 | 示例 |
|---|---|---|
| %d | 读取十进制整数 | scanf("%d", &num); |
| %i | 读取整数(可识别八进制/十六进制前缀) | scanf("%i", &num); |
| %u | 读取无符号十进制整数 | scanf("%u", &num); |
| %f | 读取浮点数 | scanf("%f", &fnum); |
| %lf | 读取双精度浮点数 | scanf("%lf", &dnum); |
| %c | 读取单个字符 | scanf("%c", &ch); |
| %s | 读取字符串(不包含空格) | scanf("%s", str); |
| %x | 读取十六进制整数 | scanf("%x", &hex); |
| %o | 读取八进制整数 | scanf("%o", &oct); |
| %% | 读取百分号 | scanf("%%"); |
3. 高级用法
3.1 宽度限定符
可以指定读取的最大字符数:
c
char str[10];
scanf("%9s", str); // 最多读取9个字符,保留1个给'\0'
3.2 跳过某些输入
使用*可以跳过某些输入项:
c
int year, month;
scanf("%d-%*d-%d", &year, &month); // 输入"2023-05-15"会跳过中间的05
3.3 扫描集
使用%[ ]可以指定接受的字符集:
c
char vowels[10];
scanf("%[aeiou]", vowels); // 只读取元音字母
反向扫描集(使用^):
c
char no_space[50];
scanf("%[^\n]", no_space); // 读取直到换行符
4. 常见问题与注意事项
4.1 缓冲区问题
c
int num;
char ch;
scanf("%d", &num); // 输入数字后按回车
scanf("%c", &ch); // 会读取之前输入的回车符
解决方案:
-
在
%c前加空格:cscanf(" %c", &ch); // 空格会跳过空白字符 -
使用
getchar()清空缓冲区
4.2 字符串输入限制
%s会读取到第一个空白字符(空格、制表符、换行符)为止:
c
char name[20];
scanf("%s", name); // 输入"John Doe"只会读取"John"
解决方案:
c
scanf("%[^\n]", name); // 读取整行(不包括换行符)
// 或使用fgets()
fgets(name, sizeof(name), stdin);
4.3 输入验证
scanf()不会检查输入是否匹配变量类型:
c
int num;
scanf("%d", &num); // 如果输入"abc",num不会被赋值
解决方案:
c
if (scanf("%d", &num) != 1) {
printf("输入无效!\n");
while(getchar() != '\n'); // 清空缓冲区
}
安全替代方案
由于scanf()存在缓冲区溢出风险,推荐使用:
c
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &num); // 从字符串解析
4.4 综合代码示例
c
#include <stdio.h>
int main() {
int id, age;
char name[50];
float score;
printf("请输入学生信息(ID 年龄 姓名 分数):");
// 使用fgets+sscanf更安全
char input[100];
fgets(input, sizeof(input), stdin);
if (sscanf(input, "%d %d %49s %f", &id, &age, name, &score) != 4) {
printf("输入格式错误!\n");
return 1;
}
printf("学生信息:\n");
printf("ID:%d\n", id);
printf("姓名:%s\n", name);
printf("年龄:%d\n", age);
printf("分数:%.2f\n", score);
return 0;
}