尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

[C语言] sscanf如何实现sscanf_s?

[C语言] sscanf如何实现sscanf_s? 在MCU中并不支持sscanf_s所以我们只能通过sscanf实现。charuser[33]{0};charpass[33]{0};sscanf_s(buf,%s %s,user,pass);// 用 sscanf实现sscanf(buf,%32[^ ] %32[^ ],user,pass);C 库函数 int sscanf(const char *str, const char *format, …) 从字符串读取格式化输入。声明下面是 sscanf() 函数的声明。int sscanf(const char *str, const charformat, …)参数str – 这是 C 字符串是函数检索数据的源。format – 这是 C 字符串包含了以下各项中的一个或多个空格字符、非空格字符 和 format 说明符。format 说明符形式为 [%[][width][modifiers]type]具体讲解如下参数 描述这是一个可选的星号表示数据是从流 stream 中读取的但是可以被忽视即它不存储在对应的参数中。width 这指定了在当前读取操作中读取的最大字符数。modifiers 为对应的附加参数所指向的数据指定一个不同于整型针对 d、i 和 n、无符号整型针对 o、u 和 x或浮点型针对 e、f 和 g的大小 h 短整型针对 d、i 和 n或无符号短整型针对 o、u 和 x l 长整型针对 d、i 和 n或无符号长整型针对 o、u 和 x或双精度型针对 e、f 和 g L 长双精度型针对 e、f 和 gtype 一个字符指定了要被读取的数据类型以及数据读取方式。具体参见下一个表格。前言在嵌入式 MCU 开发中标准 C 库函数的使用往往受到平台限制。例如许多 MCU 的编译器并不支持sscanf_s这类带安全后缀的函数开发者只能退而使用传统的sscanf。本文将从sscanf的声明、参数和格式化说明符入手结合 MCU 场景下的实际代码示例帮助读者正确、安全地在嵌入式环境中解析字符串。1. sscanf 函数基础1.1 函数声明与作用sscanf是 C 标准库提供的格式化输入函数其声明如下intsscanf(constchar*str,constchar*format,...);它从字符串str中读取数据并根据format指定的格式进行解析将结果存入后续可变参数指向的变量中。1.2 参数详解str数据源字符串即待解析的输入。format格式控制字符串可包含空格字符、非空格字符以及格式说明符。可变参数用于接收解析结果的变量地址。1.3 格式说明符组成格式说明符的通用形式为%[*][width][modifiers]type各字段含义如下字段说明*可选表示读取但忽略该数据不存入参数width指定本次读取的最大字符数modifiers指定数据类型大小如h短整型、l长整型/双精度、L长双精度type指定读取的数据类型及方式2. MCU 环境下的 sscanf 实践2.1 为什么 MCU 不支持 sscanf_ssscanf_s是微软在 Visual C 中提供的安全增强版本要求显式传入缓冲区大小以防范缓冲区溢出。而大多数嵌入式编译器如 GCC ARM、IAR、Keil仅提供标准 C 库的sscanf因此跨平台移植时需使用标准版本。下表从参数、安全性、平台支持和使用示例等方面对比sscanf与sscanf_s的差异对比项sscanfsscanf_s参数可变参数直接传入目标缓冲区地址不携带缓冲区大小每个缓冲区参数前需额外传入缓冲区大小如sizeof(user)安全性不检查缓冲区边界%s等格式符可能造成缓冲区溢出运行时校验缓冲区大小越界写入会被拒绝安全性更高平台支持C 标准库函数GCC ARM、IAR、Keil 等嵌入式编译器普遍支持微软 Visual C 扩展多数 MCU 编译器不提供使用示例sscanf(buf, %32[^ ] %32[^ ], user, pass);sscanf_s(buf, %s %s, user, sizeof(user), pass, sizeof(pass));可移植性跨平台、跨编译器通用仅限 Windows/Visual C 环境移植性差在 MCU 开发中由于目标编译器通常只提供标准 C 库应优先选择sscanf并通过width限制如%32[^ ]和返回值检查来弥补其安全性不足只有在明确运行于支持sscanf_s的桌面环境时才考虑使用sscanf_s以获得更强的缓冲区保护。2.2 使用 sscanf 解析用户名与密码在 MCU 中解析类似username password的字符串时可使用如下代码charuser[33]{0};charpass[33]{0};// 使用 sscanf 实现限制最大读取长度防止缓冲区溢出intretsscanf(buf,%32[^ ] %32[^ ],user,pass);// 检查返回值成功匹配并赋值的参数个数应为 2if(ret!2){// 解析失败返回错误码或设置默认值strcpy(user,default_user);strcpy(pass,default_pass);// 或者return -1; // 由调用方决定如何处理}通过%32[^ ]限制最多读取 32 个字符并在遇到空格时停止从而保证写入user和pass的数据不会越界。sscanf的返回值表示成功匹配并赋值的参数个数。当输入格式不符合预期例如缺少空格、字段缺失时返回值会小于 2此时应主动处理解析失败的情况返回错误码在函数中直接return -1由上层调用方根据错误码决定后续流程适合需要严格校验输入的场景。设置默认值为user和pass填充默认值保证程序继续运行适合对输入容忍度较高的场景。无论采用哪种策略都应在解析后先检查返回值避免使用未初始化的缓冲区内容。2.3 常见陷阱与注意事项未指定width时%s可能造成缓冲区溢出务必配合最大长度使用。解析失败时sscanf返回成功匹配并赋值的参数个数应检查返回值以判断解析是否完整。字符串中包含空格时应使用%[^...]集合格式而非%s。3. 总结sscanf是 MCU 开发中解析字符串的常用工具虽然缺少sscanf_s的安全检查但通过合理使用width限制和%[^...]格式符同样可以写出安全可靠的解析代码。理解其声明、参数和格式说明符是正确使用的前提。参考资料C 标准库参考文档sscanf函数说明嵌入式 C 编程实践字符串解析与缓冲区安全
返回列表