【20180824】【複習】複寫昨天學習的程式(檢查在string1中是否包含有string2)
阿新 • • 發佈:2019-02-15
例12:輸入兩個字串string1和string2,檢查在string1中是否包含有string2。如果有,則輸出string2在string1中的起始位置;如果沒有,則輸出“NO”;如果string2在string1中多次出現,則輸出在string1中出現的次數以及每次出現的起始位置。
/* 我寫的 */ #include<stdio.h> #include<stdlib.h> void main() { char s1[50],s2[20],*p1,*p2; int locat[10],posit=0,i=0,len2; printf("請輸入第一個字串:\n"); gets_s("%s",&s1[50]); printf("請輸入第二個字串:\n"); gets_s("%s",&s2[20]); p1=s1; p2=s2; for(int j=0;p2!='\0';j++,p2++) len2=j+1; do { if(*p1!=*p2) { p1++; posit++; } else { p1++; p2++; posit++; if((*p1++=*p2++)&&(*p2!='\0')) { locat[i]=posit-len2; i++; } else break; } }while(*p2!='\0'); if(i<1) printf("NO!\n"); else { printf("字串s1是%s\n",s1); printf("字串s2是%s\n",s2); printf("s2在s1中出現%d次\n",i); printf("出現的位置為%d ",locat); } system("pause"); return 0; }
我的問題:
1. gets_s()函式用錯。
2. 邏輯混亂。
3. 沒有考慮到s1中含有多處s2的情況:沒有對s2進行多次迴圈(每次迴圈之後,都要讓*p2再次指向s2首地址!)
4. 由上面除錯那張圖可以看出,求len2之後,p2指標指向了字串結束符'\0',因此在使用之後需要重新對*p2指標進行賦值!該問題改正之後即可得到正確答案。
/* 修改後的 */ #include<stdio.h> #include<stdlib.h> void main() { char s1[50],s2[20],*p1,*p2; int locat[10],posit=0,i=0,len2,j; printf("請輸入第一個字串:\n"); gets_s(s1); // 注意:這裡是s1,並不是s1[50]!只需要字元陣列名即可! printf("請輸入第二個字串:\n"); gets_s(s2); p1=s1; p2=s2; for(j=0;*p2!='\0';j++,p2++) len2=j+1; p1=s1; p2=s2; do { if(*p1!=*p2) { p1++; posit++; } else { while((*p1==*p2)&&(*p2!='\0')) { p1++; p2++; posit++; } if(*p2=='\0') { locat[i]=posit-len2; i++; } } p2=s2; }while(*p1!='\0'); if(i<1) printf("NO!\n"); else { printf("字串s1是%s\n",s1); printf("字串s2是%s\n",s2); printf("s2在s1中出現%d次\n",i); for(int j=0;j<i;j++) printf("出現的位置為%d ",locat[j]); printf("\n"); } system("pause"); //return 0; }
補充:(參考:擊此處檢視)
1. gets_s()函式:gets_s(字元陣列名或指標),即:gets_s(string);
2. scanf_s()函式:scanf_s("格式控制符",變數地址列表),即:scanf_s("%s",string);
疑問:為什麼locat[i]=posit-len2???(已解決)
答:因為字串2搜尋完畢時,posit又往後移動了len2的長度,所以要減去len2。
請問:是否可以搜尋到字串的首字母時,posit不再移動,這樣就不用減去len2了???
答:不可以,因為我們這裡是多次搜尋,搜尋字串2的所有位置,如果只搜尋一次,那麼可以讓它不再移動!如下圖: