字符串的基本操作纠正版

这几天正好在看字符串
在我不断的努力学习下,终于成功的
把代码完完整整一字不差的抄了下来,“嘿嘿”,可运行的时候,发现代码有错误???
我上当了??书本都是骗人的 还要我自己去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){ //插入第一种情况,总长度小于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,这样就避免了数据余留的问题了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值