定義:strstr(str1,str2) 函數用於判斷字符串str2是否是str1的子串。如果是,則該函數返回str2在str1中首次出現的地址;否則,返回NULL。
定義說的有點羞澀難懂。舉個例子就知道了。
比如:
char str2 = “cdef”;
char str1 = “abcdefgh”;
則通過函數,將返回
strstr(str1,str2) = cdefgh;
如果str1不包含有str2。
char str2 = “cxef”;
char str1 = “abcdefgh”;
則通過函數,將返回
strstr(str1,str2) = NULL;
該函數在比較字符串和對字符串的截取上有很大的幫助。但在某次使用過程中,程序出現了無法預料的錯誤。通過分析並打印顯示出strstr的返回值,才發現問題出在該函數上。
情況描述:
函數功能是,判斷出數組字符串裏的Uart2_Buf 含有“START”字符串的情況下,將截取其返回值給Mystr。然後把Uart2_Buf 內容清空,並打印出Mystr。
char Uart2_Buf[11] = "abSTARTdend;
char Mystr1[20] = {0};
char *Mystr=Mystr1;
//提取出Mystr
void test_strstr()
{
if(strstr(Uart2_Buf , "START") != NULL)
{
Mystr = strstr(Uart2_Buf , "START");//返回START即之後的值
CLR_Buf2();//把Uart2_Buf 內容清空
printf("Mystr=%s ",Mystr);
}
}
//清空Uart2_Buf
void CLR_Buf2(void)
{
u16 k;
for(k=0;k<11;k++)
{
Uart2_Buf[k] = 0X00;
}
}
結果:
上位機打印出顯示:Mystr=
Mystr爲空,沒有任何東西。
通過調試,去掉函數裏CLR_Buf2(); 不對Uart2_Buf 進行清空,再打印顯示:Mystr=STARTdend
這樣就能確定錯誤的結果跟清空Uart2_Buf 有關了,辣麼,如果不是清空Uart2_Buf ,而是給Uart2_Buf 賦值呢?
更改函數:void CLR_Buf2(void)
//Uart2_Buf 賦值'a'
void CLR_Buf2(void)
{
u16 k;
for(k=0;k<11;k++)
{
Uart2_Buf[k] = 'a';
}
}
結果:
上位機打印出顯示:Mystr=aaaaaaaaa(9個a)
居然顯示的是Uart2_Buf 的後部分(Uart2_Buf長度爲20),按正常應該顯示的是9個字符“STARTdend“纔對。
通過其他測試,只要在對Mystr顯示之前,更改了Uart2_Buf的內容,那麼顯示結果就會錯誤,而且Mystr顯示的是Uart2_Buf更改的後部分的值。
因此可以推斷出,Mystr的顯示和Uart2_Buf 地址有關,或者Mystr顯示跟相關指針有關。
那麼一定是對該函數的使用方法用錯了,或者還沒完全理解其定義。再回到這個函數定義,仔細閱讀這句:
定義:strstr(str1,str2) 函數用於判斷字符串str2是否是str1的子串。如果是,則該函數返回str2在str1中首次出現的地址;否則,返回NULL。
瞬間明白了原先覺得羞澀難懂的定義,原來strstr(str1,str2)返回的是str2在str1中首次出現的地址,也就是說,strstr(str1,str2)返回值能隨str1變化而變化,因爲他們內容有共用地址,地址一樣,輸出的內容也一樣。
結論(注意事項):
因而,在使用或者處理strstr(str1,str2)返回值之前,切記不要對str1字符串進行更改,若要更改,應該等使用完返回值後再更改!!