2017-08-07 208 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',因爲沒有它,它也可以工作。所以我不再是這樣了 –