查找位置函数
特性 | strstr | memmem |
---|---|---|
处理对象 | 以 \0 结尾的字符串 | 任意二进制数据(字符串、字节数组等) |
搜索终止条件 | 遇到 \0 停止(即使未找完) | 严格按 haystacklen 限制搜索范围 |
支持含 \0 的数据 | 不支持(\0 被视为字符串结束) | 支持(\0 被当作普通字节处理) |
参数要求 | 无需指定长度(依赖 \0 识别) | 必须指定 haystack 和 needle 的长度 |
返回值类型 | char* (字符串指针) | void* (通用内存指针) |
适用场景
用
strstr
:
处理标准 C 字符串(以\0
结尾,不含嵌入\0
),如普通文本、日志字符串等。
例如:在文本中查找关键词、解析 URL 中的路径等。用
memmem
:
处理二进制数据或含\0
的特殊字符串,如:- 网络协议报文(可能含
\0
作为分隔符) - 二进制文件(如图片、音频中的特定字节序列)
- 含
\0
的自定义格式数据(如固定长度的结构体)
- 网络协议报文(可能含
总结
strstr
是 “字符串专属查找工具”,依赖\0
识别字符串边界,适合纯文本处理。memmem
是 “通用内存查找工具”,不依赖\0
,通过显式长度参数控制搜索范围,适合二进制数据或特殊字符串。
在解析协议(如之前提到的 GNSS 报文)时,memmem
更常用,因为协议数据可能包含 \0
或二进制内容,无法用 strstr
正确处理。
while (index < g_gnss_msg_len_process) {// 1. 查找协议头char *pos = memmem(g_gnss_msg_buf_process + index, // 起始地址g_gnss_msg_len_process - index, // 剩余长度PROTOCOL_PACK_STRING[i].head, // 要找的协议头strlen(PROTOCOL_PACK_STRING[i].head) // 头长度);/*知识点一: memmem 是一个 内存搜索函数,用于在一段内存区域中查找指定的字节序列。它的功能类似于字符串查找函数 strstr,但 memmem 可以处理二进制数据(包含 \0 的数据),而 strstr 遇到 \0 会停止搜索。函数原型:void *memmem(const void *haystack, size_t haystacklen,const void *needle, size_t needlelen);haystack:要搜索的内存区域(如 GNSS 接收缓冲区)。haystacklen:要搜索的内存长度。needle:要查找的目标数据(如协议头 "$")。needlelen:目标数据的长度。返回值:如果找到,返回目标数据在内存中的地址。如果没找到,返回 NULL。*/if (pos == NULL) break; // 未找到协议头,退出当前协议解析// 2. 移动索引到协议头位置index = pos - g_gnss_msg_buf_process;