輸入兩個字串str1和str2,判斷str2是不是str1的子串,若是,請將str1中洗掉子串str2后的部分輸出(注意:若str1中含有多個str2子串,則只將str1中洗掉了最右邊的子串后的部分輸出)
c語言新手,對于陣列和字串這塊不太明白,求教
uj5u.com熱心網友回復:
strstr函式就是查找有沒有子串,不斷呼叫找到最后一個子串就好了呀for example
int delstr(char *str1, char *str2) {
if (str1==NULL||str2==NULL) return 0;
int len1 = (int)strlen(str1), len2 = (int)strlen(str2);
if (len1<len2) return 0;
else if (len2==0) return 1;
char *p1=str1, *p2=str1; //上面的代碼都是非正常資料的判斷,可以忽略,從這里開始是主要的代碼
while ((p1=strstr(p1,str2))!=NULL) { //strstr找不到子串則回傳值為NULL,否則就為找到子串的位置
p2 = p1; //記錄找到的位置
p1 += len2; //修改下一次查找的開始位置
}
if (p2 == str1) return 0; //如果子串沒找到則回傳
strcpy(p2, p2+len2); //從最后找到位置開始,復制跳過子串長度后的字串
*(str1+len1-len2) = '\0';//修改最終字串的結束符
return 1;
}
int main(int argc, const char * argv[]) {
char str1[] = {"abcdabcdab"};
char str2[] = {"cd"};
delstr(str1, str2);
printf("%s\n", str1);
return 0;
}
uj5u.com熱心網友回復:
strstr函式, 查找字串在另外一個當中的位置,找不到回傳NULL從str1最后str2等長的字串開始比較,不匹配就每次向前移動一個字符繼續比較,知道找到,或者到達頭為止
這個題目前幾天看到過一模一樣的問題
int delstr(char *str1, char *str2) {
if (str1==NULL||str2==NULL) return 0;
int len1 = (int)strlen(str1), len2 = (int)strlen(str2);
if (len1<len2) return 0;
else if (len2==0) return 1;
char * p = str1 + len1- len2; // 定位到str1最后len2長度的字串
while ( p >= str1 ) { // 沒有到頭
if ( p== strstr(p, str2) ) break; // 從后向前逐步找, 如果找到了必然是當前的指標
p --;
}
if (p < str1) return 0; //如果子串沒找到則回傳
strcpy(p, p+len2); //從最后找到位置開始,復制跳過子串長度后的字串
*(str1+len1-len2) = '\0';//修改最終字串的結束符
return 1;
}
uj5u.com熱心網友回復:
這樣是不行的,比如在c1c1c當中找c1c, 上面的代碼會找不到
uj5u.com熱心網友回復:
確實,忽略子串重疊了,應該指標一位一位移判斷
int delstr(char *str1, char *str2) {
if (str1==NULL||str2==NULL) return 0;
int len1 = (int)strlen(str1), len2 = (int)strlen(str2);
if (len1<len2) return 0;
else if (len2==0) return 1;
if (strstr(str1, str2) == NULL) return 0; //修改--》如果找不到子串直接回傳
char *p1=str1, *p2=str1;
while (*p1!='\0') { //修改
if (memcmp(p1, str2, len2)==0) { //修改--》直接用記憶體比較
p2 = p1;
}
p1++; //一位一位移
if (strlen(p1) < len2) break;
}
strcpy(p2, p2+len2);
*(str1+len1-len2) = '\0';
return 1;
}
int main(int argc, const char * argv[]) {
char str1[] = {"c1c1c"};
char str2[] = {"c1c"};
delstr(str1, str2);
printf("%s\n", str1);
return 0;
}
uj5u.com熱心網友回復:
while回圈改一下for (int i=0; i+len2<=len1; i++,p1++) {
if (memcmp(p1, str2, len2)==0) {
p2 = p1;
}
}
uj5u.com熱心網友回復:
while ((p1=strstr(p1,str2))!=NULL) { //strstr找不到子串則回傳值為NULL,否則就為找到子串的位置
p2 = p1; //記錄找到的位置
p1 += 1; //每次移一位 這樣也行吧1
}
uj5u.com熱心網友回復:
strcpy(p, p+len2);
注意 字串復制函式 不能出現記憶體重疊
這是未定義行為了
uj5u.com熱心網友回復:
查看了一下strcpy,memcpy,memmove等等的原碼,本例中應該還好(低址到高址復制,和自己回圈一個一個字符復制一樣,當然如果原碼不一樣另當別論),不過保險起見,有記憶體重疊時最好用memmove或者自己回圈https://blog.csdn.net/u012782049/article/details/39451983
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/131841.html
標籤:新手樂園
