2017-08-07 125 views
2

我目前在STM32F0上实施智能仪表的SML读取器。 一切工作正常,但我用strstrstring.h使用strstr的奇怪错误

现状存在问题:

我有一个字符数组数据,其中包含了所有进来的数据超过USART。它包含Hexnumbers和一个有效的文本字符串。

在这个字符串的某处有这个序列: {0x01,0x01,0x62,0x1b,0x52,0x00,0x55}

我想使用strstr在数据字符串中找到此子字符串的位置。

它工作得很好,这个例子字符串,总是在Datastring的开始:{0x1b,0x1b,0x1b,0x1b,0x01,0x01,0x01,0x01,0x76,0x05}

但是,如果使用其他的子串这是行不通的。

这里是我的代码:

const char needle[] = {0x01,0x01,0x62,0x1b,0x52,0x00,0x55}; 
    if((needle_ptr = strstr(Data,needle)) == NULL){ 
     //No Active Power String detected 
     flags &= ~NewPowervalue; //Reset NewPowervalue flag 
    }else{ 

     Powervalue = (needle_ptr[14]<<24) + (needle_ptr[15]<<16) + (needle_ptr[16]<<8) + (needle_ptr[17])/10000; 
     //Extract and calculate Powervalue 
     flags |= NewPowervalue;  //Set NewPowervalue flag 
     Poweroutlets(&Powervalue); 
     GPIOC->ODR ^= BLED; 
    } 

有没有人什么线索,我做错了什么?

+0

可能发生的0x00字符是strstr解释为字符串终止符的问题。 – SBS

+1

一般来说,从USART处理这些数据是因为字符串数据对我来说似乎很愚蠢。字符串是“嘿,你好吗?”如果您无法以可打印的ASCII字符(或您使用的任何字符编码)表示所有数据,则不应使用字符串函数。如果在接收的数据中嵌入了一个字符串,如果要使用字符串函数,请先解析该字符串。在处理二进制数据时使用['memcpy'](https://linux.die.net/man/3/memcpy)和朋友,或编写自己的解析函数。 – yano

+0

请注意,您(非)幸运的是0x1b ... 0x05'字符串'的作品,因为您还没有用空字节(0x00)终止该字符串,并且'strstr()'读取出数组边界。如果您使用'strstr()'或字符串处理函数,则必须确保处理以空字符结尾的字符串。正如(至少)其中一个答案所指出的,'memmem()'函数是用于有限长内存工作的'strstr()'的模拟。然而,它并不是一个POSIX函数(更不用说标准C),但它可能比所建议的更为广泛(Linux,macOS,AIX,...)。 –

回答

3

当然,它不起作用,因为0x00是asciiz终止符,并且strstr()比较asciiz终止的字符串,所以它停止在0x00比较。

您显示的另一个示例字符串因为它不包含任何0x00而起作用。

所以,它归结为你不想比较字符串(如C中定义的字符串),但内存区域。因此,如果你的运行时库有它,或者你自己写,你将不得不使用memmem()函数,这应该不是困难的。 (即使找到memmem()的一些实现的源代码应该也不困难。)

+2

非常感谢。随着memmem它工作正常!我没有在字符串末尾加上'\ 0',因为没有它,它也可以工作。所以我不再是这样了 –