這幾天正好在看字串
在我不斷的努力學習下,終于成功的
把代碼完完整整一字不差的抄了下來,“嘿嘿”,可運行的時候,發現代碼有錯誤???
我上當了??書本都是騙人的 還要我自己去debug 好家伙 好家伙
這究竟是道德的淪喪還是作者人性的泯滅 敬請觀看下面代碼
下面展示書上 代碼,
#include <stdio.h>
#include "string.h"
#define MAXLEN 40
typedef struct {
char ch[MAXLEN];
int len;
}SString;
int StrInsert(SString *s,int pos,SString t){
/*
pos為位置索引,t是插入的串.
*/
int i;
if(pos<0||pos>s->len) return false;
if(s->len+t.len<=MAXLEN){
for(i=s->len+t.len-1;i>=pos+t.len;i--)
s->ch[i]=s->ch[i-t.len];
for(i=0;i<t.len;i++)
s->ch[i+pos]=t.ch[i];
s->len=s->len+t.len;
}
else if(pos+t.len<=MAXLEN){
for(i=MAXLEN-1;i>t.len+pos-1;i--)
s->ch[i]=s->ch[i-t.len];
for(i=0;i<t.len;i++)
s->ch[i+pos]=t.ch[i];
s->len=MAXLEN;
}
else {
for(i=0;i<MAXLEN-pos;i++)
s->ch[pos+i]=t.ch[i];
s->len=MAXLEN;
}
return true;
}
int StrDelete(SString *s,int pos,int len){//洗掉從pos開始,長度為len的子字串,
int i;
if(pos<0||pos>(s->len-len)) return false;
for(i=pos+len;i<s->len;i++){
s->ch[i-len]=s->ch[i];
}
s->len=s->len-len;
return true;
}
int StrCompare(SString s,SString t){
for(int i=0;i<s.len&&i<t.len,i++;)
if(s.ch[i]!=t.ch[i]) return (s.ch[i]-t.ch[i]);
return (s.len-t.len);
}
int main(){
SString ch1={"lzcstc",6};
SString ch2={",,,",3};
StrInsert(&ch1,3,ch2);
printf("%s\n",ch1.ch);
printf("%d\n",StrCompare(ch1,ch2) );
StrDelete(&ch1,1,3);
printf("%s\n",ch1.ch);
return 0;
}
除錯結果:

奇怪了 說好洗掉1到3的子字串 怎么后面還多了呢??
仔細看StrDelete那段代碼
錯誤很明顯 操作顯然是把后面的字符往前移,那情況有三種:
1.后面那段代碼的長度小于前面洗掉的長度
2.后面那段代碼的長度大于前面洗掉的長度
3.后面那段代碼的長度等于前面洗掉的長度
那么StrDelete成立的條件 居然一個也沒有???
為什么?
因為只是資料往前移,本身存的那個資料還在,這就造成了重復,這就是我們上面的那種情況,并且前移的話,如果是條件1的情況下,那么前面的代碼不能全部被后面覆寫,前面還會有多余,
解決方案,
int StrDelete(SString *s,int pos,int len){
int i;
if(pos<0||pos>(s->len-len)) return false;
for(i=pos;i<pos+len;i++)
s->ch[i]=NULL;//這邊前面要洗掉的資料
for(i=pos+len;i<s->len;i++){
s->ch[i-len]=s->ch[i];
s->ch[i]=NULL;//這邊是后面要往前移的資料
}
s->len=s->len-len;
return true;
}
思路就是把前面要洗掉的先NULL,后面資料賦值完后再NULL,這樣就避免了資料余留的問題了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/208421.html
標籤:其他
上一篇:CSP-J2游記
下一篇:昨天的明天,也就是今天!
