目录

一、长度查询类

二、比较类

三、复制/填充类

四、连接/拼接类

五、查找/搜索类

六、转换类

七、实用工具类

八、STM32 常用技巧与陷阱

1. 避免的函数

2. 安全替代方案

3. 内存对齐与 Flash 字符串

4. RTOS 环境下的重入问题

5. Newlib 配置优化

九、quick reference 速查表


在 STM32 开发中,字符串操作主要依赖标准 C 库 <string.h> 和 <stdio.h> 中的函数。由于资源受限,通常需注意内存消耗、重入性和缓冲区安全

一、长度查询类

函数 原型 用途 STM32 注意点
strlen size_t strlen(const char *s); 返回字符串长度(不含 \0 空指针、越界风险
strnlen size_t strnlen(const char *s, size_t maxlen); 限制最大长度的 strlen STM32 推荐,防无限读取
// 示例:安全获取长度
size_t len = strnlen(buf, sizeof(buf) - 1);

二、比较类

函数 原型 用途 STM32 注意点
strcmp int strcmp(const char *s1, const char *s2); 逐字符比较(区分大小写) 返回 0 表示相等
strncmp int strncmp(const char *s1, const char *s2, size_t n); 比较前 n 个字符 STM32 推荐,防溢出
strcasecmp int strcasecmp(const char *s1, const char *s2); 不区分大小写比较 部分库支持(Newlib 有)
// 示例:安全比较命令
if (strncmp(cmd, "AT+", 3) == 0) { /* ... */ }

三、复制/填充类

函数 原型 用途 STM32 注意点
strcpy char *strcpy(char *dest, const char *src); 复制字符串(含 \0 ❌ 危险!无边界检查
strncpy char *strncpy(char *dest, const char *src, size_t n); 复制最多 n 个字符 必用,但需手动补 \0
memcpy void *memcpy(void *dest, const void *src, size_t n); 内存块复制(不关心 \0 STM32 高频使用,效率高
memset void *memset(void *s, int c, size_t n); 内存块设置 常用于清空缓冲区
// 推荐写法:strncpy + 强制终止
char buf[32];
strncpy(buf, src, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';  // 确保终止

四、连接/拼接类

函数 原型 用途 STM32 注意点
strcat char *strcat(char *dest, const char *src); 拼接字符串 ❌ 极易溢出
strncat char *strncat(char *dest, const char *src, size_t n); 最多拼接 n 个字符 需先确保 dest 有剩余空间
snprintf int snprintf(char *s, size_t n, const char *fmt, ...); 格式化拼接(推荐) C99 标准,STM32 常用
// Roson 推荐:snprintf 组合字符串(安全且灵活)
char msg[64];
int len = snprintf(msg, sizeof(msg), "TEMP:%d,HUM:%d", temp, hum);

五、查找/搜索类

函数 原型 用途 STM32 注意点
strchr char *strchr(const char *s, int c); 查找字符首次出现 返回 NULL 表示未找到
strrchr char *strrchr(const char *s, int c); 查找字符最后一次出现 常用于取文件扩展名
strstr char *strstr(const char *haystack, const char *needle); 查找子串 无则返回 NULL
strpbrk char *strpbrk(const char *s, const char *accept); 查找第一个出现在accept集合的字符 常用于分隔符解析
// 示例:查找 AT 命令返回值中的 "\r\n"
char *p = strstr(buf, "\r\n");

六、转换类

函数 原型 用途 STM32 注意点
atoi int atoi(const char *nptr); 字符串转 int 无错误处理,不推荐
atol long atol(const char *nptr); 字符串转 long 同上
strtol long strtol(const char *nptr, char **endptr, int base); 推荐,支持进制转换 可检测转换错误
sprintf int sprintf(char *s, const char *fmt, ...); 格式化输出到字符串 ❌ 无边界检查,危险
snprintf int snprintf(char *s, size_t n, ...); 安全版 sprintf STM32 必备
// 推荐:strtol 转换(带错误检查)
char *end;
long val = strtol(str, &end, 10);
if (*end != '\0') { /* 转换不完整 */ }

七、实用工具类

函数 原型 用途 STM32 场景
strtok char *strtok(char *str, const char *delim); 按分隔符切分字符串 解析 AT 命令、JSON 字段
strspn size_t strspn(const char *s, const char *accept); 返回接受字符集的跨度 跳过前导空白/固定头
strcspn size_t strcspn(const char *s, const char *reject); 返回排斥字符集的跨度 同上
memchr void *memchr(const void *s, int c, size_t n); 内存中查找字符 适用于二进制+文本混合
// 示例:解析 CSV
char *token = strtok(line, ",");
while (token) {
    process(token);
    token = strtok(NULL, ",");
}

八、STM32 常用技巧与陷阱

1. 避免的函数

// 危险!ST 标准库可能不检查边界
strcpy(dest, src);    // ❌ 禁止
strcat(dest, src);    // ❌ 禁止
sprintf(buf, "%s", str); // ❌ 禁止(溢出风险)

2. 安全替代方案

// 安全拷贝
strncpy(dest, src, sizeof(dest)-1);
dest[sizeof(dest)-1] = '\0';

// 安全格式化(STM32 强烈推荐)
snprintf(buf, sizeof(buf), "%.2f", voltage);

3. 内存对齐与 Flash 字符串

// STM32 中,字符串字面量通常在 Flash(.rodata)
// 如需放入 RAM,使用 PROGMEM 等效方案(HAL 库无,需自定义)

// 示例:RAM 中的 const 字符串
const char cmd_ok[] = "OK\r\n";
HAL_UART_Transmit(&huart1, (uint8_t*)cmd_ok, strlen(cmd_ok), 100);

4. RTOS 环境下的重入问题

// 自由RTOS下:strtok 不是线程安全的!
// 使用 strtok_r(GNU 扩展)或自行实现
char *strtok_r(char *str, const char *delim, char **saveptr);

5. Newlib 配置优化

STM32 HAL 默认使用 Newlib 或 Newlib-nano,可在 syscalls.c 中实现轻量版 _sbrk_write 后,字符串函数体积可控。


九、quick reference 速查表

// 最常用组合(STM32 推荐)
strlen()        → 长度(优先 strnlen)
strncmp()       → 安全比较
memcpy()        → 块复制(最快)
snprintf()      → 格式化输出(代替 sprintf)
strstr()        → 子串搜索
strtok_r()      → 线程安全切分
strtol()        → 带错误检查的数值转换

总结: STM32 下字符串处理的核心原则是:优先 strn 族、摒弃 str 无边界函数、强制用 snprintf、配合 RTOS 时注意重入性。**

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐