sscanf函数使用详解
一.sscanf函数
1.函数原型与基本概念
int sscanf(const char *str, const char *format, ...);
核心功能:从字符串中读取格式化输入(String Scan Formatted)
参数说明:
str:源字符串(从中读取数据)
format:格式控制字符串
...:接收数据的变量地址列表
返回值:
成功:返回成功匹配并赋值的参数个数
失败:返回EOF(通常为-1)
无任何匹配:返回0
2.工作原理图解
源字符串: "John 25 75.5"
格式字符串: "%s %d %f"
↓ ↓ ↓
↓ ↓ ↓
char* int float
变量 变量 变量
解析流程:
从左到右扫描源字符串
根据格式字符串解析数据
将解析结果存储到对应变量
返回成功赋值的参数数量
关键特性:
不修改源字符串
遇到格式不匹配立即停止
自动跳过空白字符(空格、制表符、换行符)
支持格式控制(宽度、类型等)
二.基础用法示例
1. 基本数据类型解析
char input[] = "John 25 75.5";
char name[20];
int age;
float height;
int count = sscanf(input, "%s %d %f", name, &age, &height);
printf("解析了 %d 个参数\n", count); // 输出: 3
printf("姓名: %s, 年龄: %d, 身高: %.1f\n", name, age, height);
// 输出: 姓名: John, 年龄: 25, 身高: 75.5
2. 日期解析
char date_str[] = "2023-08-15";
int year, month, day;
sscanf(date_str, "%d-%d-%d", &year, &month, &day);
printf("%04d年%02d月%02d日\n", year, month, day);
// 输出: 2023年08月15日
3. 十六进制解析
char hex_str[] = "0x1A3F";
unsigned int hex_value;
sscanf(hex_str, "%x", &hex_value);
printf("十进制: %u, 十六进制: 0x%X\n", hex_value, hex_value);
// 输出: 十进制: 6719, 十六进制: 0x1A3F
三.实际应用场景
适用场景:配置文件解析、网络协议处理、数据格式转换、日志分析、字符串数据提取等。
1.配置文件解析
char config_line[] = "timeout = 30; # connection timeout";
char key[20];
int value;
if(sscanf(config_line, "%19s = %d;", key, &value) == 2) {
printf("配置项: %s = %d\n", key, value);
}
// 输出: 配置项: timeout = 30
2.网络协议解析
char packet[] = "GET /index.html HTTP/1.1\r\nHost: www.example.com\r\n";
char method[10], path[50], protocol[10], host[50];
sscanf(packet, "%9s %49s %9s\r\nHost: %49[^\r]",
method, path, protocol, host);
printf("方法: %s\n路径: %s\n协议: %s\n主机: %s\n",
method, path, protocol, host);
/* 输出:
方法: GET
路径: /index.html
协议: HTTP/1.1
主机: www.example.com */
3.数据清洗与转换
char dirty_data[] = "Price: $1,234.56 USD";
char clean_number[20];
float price;
// 移除非数字字符(保留小数点)
sscanf(dirty_data, "%*[^0-9]%19[0-9.,]", clean_number);
// 移除千位分隔符
char *ptr = clean_number;
while(*ptr) {
if(*ptr == ',') memmove(ptr, ptr+1, strlen(ptr));
else ptr++;
}
sscanf(clean_number, "%f", &price);
printf("清洗后价格: %.2f\n", price);
// 输出: 清洗后价格: 1234.56
四.总结
1.安全检查:
验证返回值
使用宽度限制防止溢出
检查输入字符串有效性
2.错误处理:
char input[] = "InvalidData";
int value;
if(sscanf(input, "%d", &value) != 1) {
fprintf(stderr, "解析错误: %s\n", input);
// 错误恢复逻辑...
}
3.复杂解析:
分阶段解析复杂字符串
结合strchr/strstr定位关键位置
使用%[]处理不规则格式
4.性能敏感场景:
避免在循环中重复解析相同字符串
对大字符串使用指针操作而非子串复制
考虑使用strtol/strtod处理数字