C语言中uint8_t数组转字符串后用strstr查子串的写法是否正确?
问题分析与解答
你的if语句完全不正确,出现“总是返回true”是因为触发了C语言的未定义行为,具体原因如下:
strstr的使用前提错误strstr是专门处理C风格字符串的标准库函数,它要求传入的字符串必须以空字符\0(即0x00)结尾。但你的uint8_t data[8]数组里没有这个终止符,调用strstr时,函数会从数组起始位置开始,一直往内存深处读取,直到找到\0为止——这已经超出了数组的合法访问范围,属于越界读内存,结果完全不可控,“总是返回true”只是未定义行为的一种表现。类型转换与匹配逻辑的矛盾
你把二进制的uint8_t数组强转成const char*,但数组里的元素是0xcb、0xe2这类非ASCII值,而你要匹配的子串"000"对应的ASCII码是0x30、0x30、0x30。正常情况下数组里没有这些值,但因为越界读内存的未定义行为,函数可能在越界区域读到了连续的0x30,或者其他导致匹配成功的错误情况。
正确的实现方式
根据你的需求,分两种情况处理:
情况1:检查数组中是否存在连续三个二进制0x00
直接遍历数组,手动检查连续元素:
uint8_t data[8] = {0xcb,0xe2,0x3d,0x96,0x55,0xfc,0xcd,0x43}; int has_three_zero = 0; for (int i = 0; i <= 8 - 3; i++) { if (data[i] == 0 && data[i+1] == 0 && data[i+2] == 0) { has_three_zero = 1; break; } } if (has_three_zero) { // 处理逻辑 }
情况2:检查数组中是否存在连续三个ASCII字符'0'(即0x30)
同样用遍历实现:
uint8_t data[8] = {0xcb,0xe2,0x3d,0x96,0x55,0xfc,0xcd,0x43}; int has_three_0 = 0; for (int i = 0; i <= 8 - 3; i++) { if (data[i] == '0' && data[i+1] == '0' && data[i+2] == '0') { has_three_0 = 1; break; } } if (has_three_0) { // 处理逻辑 }
若一定要用字符串处理函数(仅当数组元素都是合法ASCII且无内嵌0x00时)
必须给数组添加\0终止符,且数组长度要预留位置:
// 数组长度改为9,最后一位设为0作为终止符 uint8_t data[9] = {0xcb,0xe2,0x3d,0x96,0x55,0xfc,0xcd,0x43, 0}; if (strstr((const char*)data, "000") != NULL) { // 处理逻辑 }
但这种方式仅适用于数组中所有元素都是有效的ASCII字符(没有0x00,除非是末尾的终止符),否则strstr会在遇到第一个0x00时停止扫描。
内容的提问来源于stack exchange,提问作者pacionet
相关产品推荐
相关产品推荐

