北京信息工程学院、北京信息科技大学 软件工程课程设计全部代码,希望对北信的下一代有用!
来源:互联网 发布:mysql不允许远程连接 编辑:程序博客网 时间:2024/04/25 08:38
cpp内容:1000多行吧。
头文件内容:
// vicht.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#define len 4
#define LINESIZE 80 /*每行长度为80个字符*/
//建立一个TEXT 模型
struct TEXT
{
struct TEXT *prior;
char str[LINESIZE+1]; /*包括 '�' 在内,设置长度为LINESIZE+1*/
struct TEXT *next; //前驱指针
};
struct TEXT *TPTR,*BPTR,*KPTR,*QPTR,*SPTR,*YPTR,*XPTR,*FPTR;
struct TEXT *ptr,*work;
int CHG,ERR,CMP,IND,CTR,i,NUM;
char ch,BUF;
char IN[LINESIZE+1],NUMD[len],MAT[LINESIZE],REP[LINESIZE],temp[LINESIZE];
/*-----------------------声明功能开始-----------------------------------*/
//被主程序调用的函数
//初始化函数
void INIT();
//读取一行函数
void READ_LINE();
//输入函数
void INPUT();
//到最顶行函数
void TOP();
//向上函数
void UP();
//下一行函数
void NEXT();
//确认函数
void ENTER();
//列出list函数
void LIST();
//删除函数
void DELETE();
//替换函数
void REPLACE();
//查找函数
void FIND();
//插入函数
void INSERT();
//拷贝函数
void COPY();
//存储函数
void STORE();
//写一行函数
void WRITE_LINE();
//一些内部函数
void CONVERT(int l);
void GO_EDIT();
void CONNECT();
void INSERT_CHAIN();
int GET_NUMBER();
void DELETE_LINK();
int GET_STRING1();
int GET_STRING2();
void COMP();
void BACK(int up,int xb);
void HELP();
/*------------------------声明功能结束----------------------------------*/
/*
#1 主要起调度作用
*/
void main()
{
//初始化程序
INIT();
//开始运行程序,无限循环
//如果遇到Q或者q则退出程序
//否则继续循环,完成功能
while(1)
{
if(IND==0)
printf(" :"); /*命令提示符*/
READ_LINE();
i=0;
if(IND!=0)
INPUT();
else
{
ch=IN[0];
if(ch=='T'||ch=='t')
TOP();
else if(ch=='U'||ch=='u')
UP();
else if(ch=='N'||ch=='n')
NEXT();
else if(ch=='E'||ch=='e')
ENTER();
else if(ch=='L'||ch=='l')
LIST();
else if(ch=='D'||ch=='d')
DELETE();
else if(ch=='R'||ch=='r')
REPLACE();
else if(ch=='F'||ch=='f')
FIND();
else if(ch=='I'||ch=='i')
INSERT();
else if(ch=='C'||ch=='c')
COPY();
else if(ch=='S'||ch=='s')
STORE();
else if(ch=='Q'||ch=='q')
exit(0);
else if(ch=='H'||ch=='h')
HELP();
else
{
strcpy(IN,"?! Shit cannot understand U!�"); /*不正确的编辑命令响应*/
WRITE_LINE();
}
}
}
}
/*
#2 初始化正文编辑程序
*/
void INIT()
{
printf("Welcome to ShitNotepad 1.0 RN!! ");
printf("It is Really a piece of shit! ");
printf("================================================");
HELP();
FPTR=(struct TEXT*)malloc(sizeof(struct TEXT));
FPTR->prior=0;
FPTR->next=0;
CMP=CHG=ERR=0;
IND=0;
BPTR=TPTR=0; /*无正文链*/
KPTR=QPTR=0; /*无工作链*/
strcpy(IN,"Enter Command and try this shit now!�");
WRITE_LINE();
}
/*
#3 从终端接收一行正文并且把它存到缓冲器IN中
*/
void READ_LINE()
{
i=0;
BUF=getchar();
while(i<LINESIZE && BUF!=' ')
{
if(BUF=='@')
{
if(i!=0)
{
if(IN[i-1]<0)
{
IN[--i]=' '; /*是汉字删掉两个字节*/
IN[--i]=' ';
}
else
IN[--i]=' '; /*不是汉字删掉一个字节*/
}
}
if(BUF=='#')
i=0;
if(BUF<0)
{
IN[i++]=BUF;
IN[i++]=getchar();
}
else if(BUF!='@' && BUF!='#')
IN[i++]=BUF;
BUF=getchar();
}
if(i>=LINESIZE||BUF==' ')
{
if(i==0)
IN[i++]=' ';
IN[i]='';/*存入字符串结束标志*/
}
fflush(stdin);
}
/*
#4 把IN中的内容输出到终端
*/
void WRITE_LINE()
{
printf(" %s",IN);
}
/*
#5 从缓冲器IN取来一行正文放到正文文件中
*/
void INPUT()
{
ch=IN[0];
if(IND==1) /*尚未接收到正文*/
{
if(ch==' ')
GO_EDIT(); /*转到编辑模式*/
else
{
if(FPTR==0)
{
strcpy(IN,"NOFREE!�");
WRITE_LINE();
}
else
{
ptr=FPTR; /*YPRT在此模块内主要起链接串之用*/
XPTR=FPTR;
strcpy(XPTR->str,IN);
IND=2;
}
}
}
else
{
if(ch==' ') /*空行,从自由链把正文移到正文链并转到编辑模式*/
{
CONNECT();
INSERT_CHAIN();
GO_EDIT();
}
else
{
XPTR->next=(struct TEXT*)malloc(sizeof(struct TEXT));
if(XPTR->next==0)
{
CONNECT();
INSERT_CHAIN();
strcpy(IN,"NOFREE!�");
WRITE_LINE();
GO_EDIT(); /*内存空间不足,自动转到编辑模式*/
}
else
{
XPTR=XPTR->next;
XPTR->prior=ptr;
ptr=XPTR;
XPTR->next=0;
strcpy(XPTR->str,IN);
}
}
}
}
/*
#6 转到编辑模式
*/
void GO_EDIT()
{
IND=0;
strcpy(IN,"EDIT!�");
WRITE_LINE();
}
/*
#7 分离后,只需让TPTR,BPTR指向自由链,但是要让FPTR指向一个新的结点,否则将失去指向
*/
void CONNECT()
{
YPTR=FPTR;
FPTR=(struct TEXT*)malloc(sizeof(struct TEXT));
if(FPTR!=0)
{
FPTR->prior=0;
FPTR->next=0;
}
}
/*
#8 把新输入的正文加到正文链中,紧接在当前行的后面。开始时YPTR指向输入正文的第一行,
XPTR指向最后一行。指针把原有的正文分成两部分,分别为前半和后半。
*/
void INSERT_CHAIN()
{
if(BPTR==0)
{
if(TPTR==0) /*原来没有正文链*/
{
TPTR=YPTR; /*使分离出的自由链的第一行为新的正文链的第一行,自由链的最后一行为新的正文链的最后一行*/
BPTR=XPTR;
}
else
{
XPTR->next=TPTR;
TPTR->prior=XPTR;
TPTR=YPTR;
BPTR=XPTR;
}
}
else /*当前行不是虚拟行*/
{
if(BPTR->next==0) /*当前行指针BPTR指向正文链中最后一行*/
{
BPTR->next=YPTR;
YPTR->prior=BPTR;
BPTR=XPTR;
}
else /*BPTR指向正文链的中间某个结点*/
{
SPTR=BPTR->next;
BPTR->next=YPTR;
YPTR->prior=BPTR;
XPTR->next=SPTR;
SPTR->prior=XPTR;
BPTR=XPTR;
}
}
}
/*
#9 使BPTR指向虚拟行
*/
void TOP()
{
BPTR=0;
printf(" Move to virtual line successfully!");
}
/*
#10 进入输入模式
*/
void ENTER()
{
IND=1;
strcpy(IN,"INPUT! �");
WRITE_LINE();
}
/*
#11 使指针BPTR从当前行往上移N行,并且打印新的当前行
*/
void UP()
{
int GET_NUMBER();
if(GET_NUMBER()==1) /*不成功返回*/
return;
CTR=NUM; /*调用GET_NUMBER()得到的数在NUM中*/
if(TPTR==0)
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
if(BPTR==0)
{
strcpy(IN,"TOF!�");
WRITE_LINE();
return;
}
while(CTR>0)
{
BPTR=BPTR->prior;
CTR--;
if(BPTR==0)
{
strcpy(IN,"TOF!�");
WRITE_LINE();
return;
}
}
strcpy(IN,BPTR->str); /*打印当前行*/
WRITE_LINE();
}
/*
#12 从编辑命令中取来数N,把它存在缓冲器NUMD中。如果N是空格,则在CONVERT()中把补缺值置1
*/
int GET_NUMBER()
{
int l=0,xb,flag=0;
ERR=0;
if(IN[++i]!=' ')
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb=++i;
while(IN[xb]!='') /*计算正确命令从空格后第一个字符起到最后的字符长度l*/
{
xb++;
l++;
}
if(l>len) /*当字符长度l>4时,即输入的数字个数>4,认为命令出错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb=i;
while(IN[xb]!='')
{
if((IN[xb]<48||IN[xb]>57)&&IN[xb]!=' ') /*此命令输入的N中一旦出现既不是数字又不是空格的字符认为出错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb++;
}
xb=i;
while(IN[xb]!='') /*经过上面两个判断,N中为只包含数字和空格且长度<=4的字符,这里用来判断N中是否全为空格*/
{
if(IN[xb]!=' ')
{
flag=1;
break;
}
xb++;
}
if(!flag) /*全为空格,缺省值为*/
{
NUM=1;
return(0);
}
else
{
l=0;
while(IN[xb]!='')
{
if(IN[xb]>=48 && IN[xb]<=57)
NUMD[l++]=IN[xb];
else /*一旦出现数字,就要求N中一直到最后必须全为数字,否则认为出错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb++;
}
CONVERT(l);
}
if(ERR==1) /*ERR=1表示命令有错,发现错误后重置ERR=0,备以后判断*/
{
ERR=0;
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
else
return(0); /*成功返回*/
}
/*
#13 此模块把数组NUMD中用字符形式表示的十进制数转变成十进制数的内部表示形式,并存放到NUMD中
若NUMD中全是空格,则NUM中放1.如果NUM值为0,则把ERR置1以示错误,否则置0,表明转变成功
*/
void CONVERT(int l)
{
int m=0,dig;
NUM=0;
while(m<l)
{
dig=NUMD[m]-'0';
NUM=NUM*10+dig;
m++;
}
if(NUM==0)
ERR=1;
}
/*
#14 把指针BPTR从当前行往下移N行
*/
void NEXT()
{
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
{
BPTR=TPTR;
CTR--;
}
}
while(CTR>0)
{
if(BPTR->next==0)
{
strcpy(IN,"EOF!�");
WRITE_LINE();
return;
}
BPTR=BPTR->next;
CTR--;
}
strcpy(IN,BPTR->str);
WRITE_LINE();
}
/*
#15 输出正文链中从当前行开始的N行正文
*/
void LIST()
{
if(GET_NUMBER()==1)
return;
CTR=NUM; /*调用GET_NUMBER()得到的数在NUM中*/
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR; /*第一行作为当前行*/
}
strcpy(IN,BPTR->str);
CTR--;
WRITE_LINE();
while(CTR>0)
{
if(BPTR->next==0)
{
strcpy(IN,"EOF!�");
WRITE_LINE();
return;
}
BPTR=BPTR->next;
strcpy(IN,BPTR->str);
CTR--;
WRITE_LINE();
}
}
/*
#16 删掉正文链中从当前行开始的N行正文,并且释放后占的存贮空间,如果N是空格,则补缺值为1
*/
void DELETE()
{
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0)
{
if(TPTR==0)
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR;
}
DELETE_LINK();
while(YPTR!=XPTR) /*释放后占空间*/
{
YPTR=YPTR->next;
free(YPTR->prior);
}
free(XPTR);
printf(" delete successfully!");
}
/*
#17 从正文链中把要删掉的那些行分离下来。使YPTR和XPTR分别指向要被删掉的第一行和最后一行
*/
void DELETE_LINK()
{
YPTR=BPTR;
XPTR=BPTR;
CTR--;
while(CTR>0 && XPTR->next!=0)
{
XPTR=XPTR->next;
CTR--;
}
if(XPTR->next==0) /*已删到正文链末尾*/
{
if(CTR>0) /*要求删掉的行比能删掉的行多*/
{
strcpy(IN,"EOF!�");
WRITE_LINE();
}
if(YPTR->prior==0) /*从第一行开始删除*/
{
BPTR=0;
TPTR=0;
}
else /*还有正文链*/
{
BPTR=YPTR->prior;
BPTR->next=0;
}
}
else /*没有删到正文链末尾*/
{
BPTR=XPTR->next; /*BPTR指向被删掉的后面第一行,作为新的当前行*/
if(YPTR->prior==0)/*从第一行开始删*/
{
TPTR=BPTR;
TPTR->prior=0;
}
else /*从正文链的中间某个结点删,但是没有删到正文链末尾*/
{
SPTR=YPTR->prior;
SPTR->next=BPTR;
BPTR->prior=SPTR;
}
}
}
/*
#18 把正文链从当行开始的N行正文复制到工作链,这N行正文并不从正文链删除
思路:直接从正文链复制到工作链,当工作链空间不够用时提示用户输入了多少行
当复制的行数>可得到的行数,印出信息EOF
*/
void COPY()
{
int line=0;
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*无正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR; /*正文链第一行作为虚拟行*/
}
XPTR=BPTR;
while(CTR>0 && XPTR->next!=0)
{
if(KPTR==0) /*原来没有工作链*/
{
KPTR=(struct TEXT*)malloc(sizeof(struct TEXT));
if(!KPTR)
{
printf(" There is no free space!");
return;
}
work=KPTR;
KPTR->prior=0;
KPTR->next=0;
QPTR=KPTR;
strcpy(QPTR->str,XPTR->str);
XPTR=XPTR->next;
CTR--;
line++;
}
else /*已存在工作链*/
{
QPTR->next=(struct TEXT*)malloc(sizeof(struct TEXT));
if(!QPTR->next)
{
printf(" No free space,only copied %d lines!",line);
BPTR=XPTR;
return;
}
QPTR=QPTR->next;
QPTR->prior=work;
work=QPTR;
QPTR->next=0;
strcpy(QPTR->str,XPTR->str);
CTR--;
XPTR=XPTR->next;
line++;
}
}
if(XPTR->next==0)
{
if(CTR>0) /*退出上面的循环时最后一行尚未复制*/
{
BPTR=XPTR;
strcpy(IN,"EOF!�");
WRITE_LINE();
QPTR->next=(struct TEXT*)malloc(sizeof(struct TEXT));
if(!QPTR->next)
{
printf(" No free space,only copied %d lines!",line);
return;
}
QPTR=QPTR->next;
QPTR->prior=work;
work=QPTR;
QPTR->next=0;
strcpy(QPTR->str,XPTR->str);
CTR--;
XPTR=XPTR->next;
}
else
BPTR=XPTR;
}
else
BPTR=XPTR;
}
/*
#19 把正文链中从当前行开始的N行正文同其他正文分离开,然后把他们移到工作链的尾部。
调用Delete_Link()后,YPTR,XPTR分别指向要分离正文的第一行和最后一行。
*/
void STORE()
{
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR; /*第一行作为当前行*/
}
DELETE_LINK();
if(KPTR==0)
{
KPTR=YPTR;
KPTR->prior=0;
}
else
{
QPTR->next=YPTR;
YPTR->prior=QPTR;
}
QPTR=XPTR;
work=QPTR;
QPTR->next=0;
}
/*
#20 把工作链中的全部正文都插到正文链中,紧接在当前行后面
*/
void INSERT()
{
if(KPTR==0)
{
printf(" There is no text in workspace!");
return;
}
printf(" INSERT SUCCESSFULLY!");
YPTR=KPTR;
XPTR=QPTR;
KPTR=0;
QPTR=0;
INSERT_CHAIN();
}
/*
#21 从命令中取得第一个字符串,并且把它存到缓冲器MAT中
*/
int GET_STRING1()
{
int j=0;
void WRITE_LINE();
if(IN[++i]!=' ') /*缓冲器IN中的第二个字符不是空格,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
if(IN[++i]!='/') /*缓冲器IN中的第三个字符不是斜线,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
if(IN[++i]=='/') /*空字符串,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
while(IN[i]!='' && IN[i]!='/') /*找到第二条斜线*/
MAT[j++]=IN[i++];
if(IN[i]=='') /*缺第二条斜线,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
i++; /*i指向第二条斜线后的第一个字符*/
MAT[j]='';
return(0);
}
/*
#22 这个模块比较缓冲器IN中从第I个字符开始的子字符串和缓冲器MAT中的字符串,开关CMP指示比较结果
1表示匹配,0表示不匹配
*/
void COMP()
{
int l,xb=0,up=0;
while(strlen(IN)-up>=strlen(MAT)) /*IN中剩余字符串的长度>MAT中的字符串长度,继续寻找*/
{
for(l=0;l<strlen(MAT);l++) temp[l]=IN[xb++]; /*temp是临时数组,存放IN中从第xb个字符起长度为strlen(MAT)的子串*/
temp[l]='';
if(strcmp(temp,MAT)==0) /*字符串匹配,CMP置1,返回*/
{
CMP=1;
return;
}
up++;
xb=up;
}
}
/*
#23 从当前行下面一行开始扫描正文链,使当前行指针指向第一次出现字符串STRING1的那一行
*/
void FIND()
{
if(GET_STRING1()==1) /*不成功返回*/
return;
if(TPTR==0) /*没有正文*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
if(BPTR==0)
BPTR=TPTR;
else
{
if(BPTR->next!=0) /*当前行不是正文链最后一行,从下一行开始扫描*/
BPTR=BPTR->next;
else
{
strcpy(IN,"EOF!�");
WRITE_LINE();
return;
}
}
while(BPTR->next!=0) /*逐行扫描*/
{
strcpy(IN,BPTR->str);
COMP();
if(CMP==1)
{
CMP=0;
WRITE_LINE();
return;
}
BPTR=BPTR->next;
}
strcpy(IN,BPTR->str); /*退出循环后,最后一行还没有扫描*/
COMP();
if(CMP==1)
{
CMP=0;
WRITE_LINE();
}
else
{
strcpy(IN,"EOF!�");
WRITE_LINE();
}
}
/*
#24 从编辑命令中取第二个字符串STRING2,开始时指针i指向第二条斜线的后的第一个字符。取得的字符串放在
缓冲器REP中
*/
int GET_STRING2()
{
int k=0;
if(IN[i]=='' || IN[i]=='/') /*缺第三条斜线或第二个字符串为空串*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
while(IN[i]!='/' && IN[i]!='')
REP[k++]=IN[i++];
if(IN[i]=='') /*IN中总是以�结束,如果以此条件退出循环,说明肯定没有第三条斜线,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
REP[k]=''; /*成功找到第二个字符串*/
return(0);
}
/*
#25 在从当前行开始的N行正文中,每出现一个字符串STRING1,就用字符串STRING2来代替
*/
void REPLACE()
{
int xhbl,xj=0,sj=0;
struct TEXT *pre; /*PRE总是指向BPTR的前一个结点*/
if(GET_STRING1()==1)
{
strcpy(IN,"?!�");
WRITE_LINE();
return;
}
if(GET_STRING2()==1)
{
strcpy(IN,"?!�");
WRITE_LINE();
return;
}
if(GET_NUMBER()==1)
{
strcpy(IN,"?!�");
WRITE_LINE();
return;
}
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR;
}
CTR=NUM;
CHG=0;
while(CTR>0 && BPTR!=0)
{
strcpy(IN,BPTR->str);
while(strlen(IN)-xj>=strlen(MAT))/*检查机制:从IN第一个字符起,取长度为strlen(MAT)的子串放到temp中,和*/
{ /*MAT比较之后,再从IN第二个字符起,取长度为strlen(MAT)的子串放到temp中*/
for(xhbl=0;xhbl<strlen(MAT);xhbl++)temp[xhbl]=IN[sj++];
temp[xhbl]='';
if(strcmp(temp,MAT)==0)
{
CHG=1;
BACK(xj,sj);
sj+=strlen(REP)-strlen(MAT); /*替换后,从替换后的下一个字符起检查串有无其它和MAT相同的子中*/
xj=sj;
continue;
}
xj++;
sj=xj;
}
if(CHG==1)
{
CHG=0;
strcpy(BPTR->str,IN);
WRITE_LINE();
}
pre=BPTR;
BPTR=BPTR->next;
CTR--;
xj=0; /*sj,xj重置初值,扫描下一行*/
sj=0;
}
if(BPTR==0) /*若出现要求代替的行数多于能得到的行数,显示信息EOF!*/
if(CTR>0)
{
strcpy(IN,"EOF!�");
WRITE_LINE();
}
BPTR=pre;
}
/*
#26 此模块用来完成替换
up指向IN中一子串的首地址,此子串与MAT匹配,xb指向此子串的后面的第一个字符
*/
void BACK(int up,int xb)
{
int sub,len1,len2,leftspa,j=0,l;
len1=strlen(MAT);
len2=strlen(REP);
sub=len2-len1; /*求出用REP中替换IN中的子串后增加了几个字符,可能为负数*/
leftspa=LINESIZE-strlen(IN); /*求IN中的剩余空间*/
if(len1==len2) /*要替换的串与被替换的串长度相等*/
for(l=1;l<=len2;l++)
IN[up++]=REP[j++]; /*从up位置起逐个替换原子串*/
if(len1>len2)
{
for(l=1;l<=len2;l++)
IN[up++]=REP[j++];
up=xb-up; /*求xb到up之间用几个字符*/
while(IN[xb]!='')
{
IN[xb-up]=IN[xb]; /*从xb位置起逐个后移字符,位移量为up*/
xb++;
}
IN[xb-up]='';
}
if(len1<len2)
{
if(leftspa>=sub) /*IN中剩余空间大于等于要增加的字符,此时空间够用*/
{
for(l=strlen(IN);l>=xb;l--)
IN[l+sub]=IN[l]; /*从�起逐个后移字符,腾出空间*/
for(l=1;l<=len2;l++)
IN[up++]=REP[j++]; /*空间已腾出,逐个替换即可*/
}
else /*IN中空间小于要增加的字符数,需进行截尾操作*/
{
for(l=strlen(IN)-(sub-leftspa)-1;l>=xb;l--) /*算出需截掉的字符个数为sub-leftspa,
IN[l+sub]=IN[l]; /*只需从strlen(IN)-(sub-leftspa)-1开始逐个后移字符*/
IN[LINESIZE]='';
for(l=1;l<=len2 && l<LINESIZE-up;l++) /*逐个替换需保证循环次数,只能从up到�之间*/
IN[up++]=REP[j++];
}
}
}
/*
ex: 显示帮助!
*/
void HELP()
{
printf(" _______________________________________________________________");
printf(" | ShitNotepad HELP |");
printf(" ---------------------------------------------------------------");
printf(" | Input T to the TOP |");
printf(" | Input U n to UP n line |");
printf(" | Input N n to NEXT n line |");
printf(" | Input E to ENTER |");
printf(" | Input R /STR1/STR2/ n to REPLACE a word in line n |");
printf(" | Input C n to COPY line n |");
printf(" | Input L n to LIST line n |");
printf(" | Input F /SFTR1/ to FIND a word in line n |");
printf(" | Input S n to STORE line n |");
printf(" | Input D n to DELETE line n |");
printf(" | Input I to INSERT |");
printf(" | Input Q to QUIT |");
printf(" | Input H for the Help |");
printf(" ---------------------------------------------------------------");
}
//
#include "stdafx.h"
#define len 4
#define LINESIZE 80 /*每行长度为80个字符*/
//建立一个TEXT 模型
struct TEXT
{
struct TEXT *prior;
char str[LINESIZE+1]; /*包括 '�' 在内,设置长度为LINESIZE+1*/
struct TEXT *next; //前驱指针
};
struct TEXT *TPTR,*BPTR,*KPTR,*QPTR,*SPTR,*YPTR,*XPTR,*FPTR;
struct TEXT *ptr,*work;
int CHG,ERR,CMP,IND,CTR,i,NUM;
char ch,BUF;
char IN[LINESIZE+1],NUMD[len],MAT[LINESIZE],REP[LINESIZE],temp[LINESIZE];
/*-----------------------声明功能开始-----------------------------------*/
//被主程序调用的函数
//初始化函数
void INIT();
//读取一行函数
void READ_LINE();
//输入函数
void INPUT();
//到最顶行函数
void TOP();
//向上函数
void UP();
//下一行函数
void NEXT();
//确认函数
void ENTER();
//列出list函数
void LIST();
//删除函数
void DELETE();
//替换函数
void REPLACE();
//查找函数
void FIND();
//插入函数
void INSERT();
//拷贝函数
void COPY();
//存储函数
void STORE();
//写一行函数
void WRITE_LINE();
//一些内部函数
void CONVERT(int l);
void GO_EDIT();
void CONNECT();
void INSERT_CHAIN();
int GET_NUMBER();
void DELETE_LINK();
int GET_STRING1();
int GET_STRING2();
void COMP();
void BACK(int up,int xb);
void HELP();
/*------------------------声明功能结束----------------------------------*/
/*
#1 主要起调度作用
*/
void main()
{
//初始化程序
INIT();
//开始运行程序,无限循环
//如果遇到Q或者q则退出程序
//否则继续循环,完成功能
while(1)
{
if(IND==0)
printf(" :"); /*命令提示符*/
READ_LINE();
i=0;
if(IND!=0)
INPUT();
else
{
ch=IN[0];
if(ch=='T'||ch=='t')
TOP();
else if(ch=='U'||ch=='u')
UP();
else if(ch=='N'||ch=='n')
NEXT();
else if(ch=='E'||ch=='e')
ENTER();
else if(ch=='L'||ch=='l')
LIST();
else if(ch=='D'||ch=='d')
DELETE();
else if(ch=='R'||ch=='r')
REPLACE();
else if(ch=='F'||ch=='f')
FIND();
else if(ch=='I'||ch=='i')
INSERT();
else if(ch=='C'||ch=='c')
COPY();
else if(ch=='S'||ch=='s')
STORE();
else if(ch=='Q'||ch=='q')
exit(0);
else if(ch=='H'||ch=='h')
HELP();
else
{
strcpy(IN,"?! Shit cannot understand U!�"); /*不正确的编辑命令响应*/
WRITE_LINE();
}
}
}
}
/*
#2 初始化正文编辑程序
*/
void INIT()
{
printf("Welcome to ShitNotepad 1.0 RN!! ");
printf("It is Really a piece of shit! ");
printf("================================================");
HELP();
FPTR=(struct TEXT*)malloc(sizeof(struct TEXT));
FPTR->prior=0;
FPTR->next=0;
CMP=CHG=ERR=0;
IND=0;
BPTR=TPTR=0; /*无正文链*/
KPTR=QPTR=0; /*无工作链*/
strcpy(IN,"Enter Command and try this shit now!�");
WRITE_LINE();
}
/*
#3 从终端接收一行正文并且把它存到缓冲器IN中
*/
void READ_LINE()
{
i=0;
BUF=getchar();
while(i<LINESIZE && BUF!=' ')
{
if(BUF=='@')
{
if(i!=0)
{
if(IN[i-1]<0)
{
IN[--i]=' '; /*是汉字删掉两个字节*/
IN[--i]=' ';
}
else
IN[--i]=' '; /*不是汉字删掉一个字节*/
}
}
if(BUF=='#')
i=0;
if(BUF<0)
{
IN[i++]=BUF;
IN[i++]=getchar();
}
else if(BUF!='@' && BUF!='#')
IN[i++]=BUF;
BUF=getchar();
}
if(i>=LINESIZE||BUF==' ')
{
if(i==0)
IN[i++]=' ';
IN[i]='';/*存入字符串结束标志*/
}
fflush(stdin);
}
/*
#4 把IN中的内容输出到终端
*/
void WRITE_LINE()
{
printf(" %s",IN);
}
/*
#5 从缓冲器IN取来一行正文放到正文文件中
*/
void INPUT()
{
ch=IN[0];
if(IND==1) /*尚未接收到正文*/
{
if(ch==' ')
GO_EDIT(); /*转到编辑模式*/
else
{
if(FPTR==0)
{
strcpy(IN,"NOFREE!�");
WRITE_LINE();
}
else
{
ptr=FPTR; /*YPRT在此模块内主要起链接串之用*/
XPTR=FPTR;
strcpy(XPTR->str,IN);
IND=2;
}
}
}
else
{
if(ch==' ') /*空行,从自由链把正文移到正文链并转到编辑模式*/
{
CONNECT();
INSERT_CHAIN();
GO_EDIT();
}
else
{
XPTR->next=(struct TEXT*)malloc(sizeof(struct TEXT));
if(XPTR->next==0)
{
CONNECT();
INSERT_CHAIN();
strcpy(IN,"NOFREE!�");
WRITE_LINE();
GO_EDIT(); /*内存空间不足,自动转到编辑模式*/
}
else
{
XPTR=XPTR->next;
XPTR->prior=ptr;
ptr=XPTR;
XPTR->next=0;
strcpy(XPTR->str,IN);
}
}
}
}
/*
#6 转到编辑模式
*/
void GO_EDIT()
{
IND=0;
strcpy(IN,"EDIT!�");
WRITE_LINE();
}
/*
#7 分离后,只需让TPTR,BPTR指向自由链,但是要让FPTR指向一个新的结点,否则将失去指向
*/
void CONNECT()
{
YPTR=FPTR;
FPTR=(struct TEXT*)malloc(sizeof(struct TEXT));
if(FPTR!=0)
{
FPTR->prior=0;
FPTR->next=0;
}
}
/*
#8 把新输入的正文加到正文链中,紧接在当前行的后面。开始时YPTR指向输入正文的第一行,
XPTR指向最后一行。指针把原有的正文分成两部分,分别为前半和后半。
*/
void INSERT_CHAIN()
{
if(BPTR==0)
{
if(TPTR==0) /*原来没有正文链*/
{
TPTR=YPTR; /*使分离出的自由链的第一行为新的正文链的第一行,自由链的最后一行为新的正文链的最后一行*/
BPTR=XPTR;
}
else
{
XPTR->next=TPTR;
TPTR->prior=XPTR;
TPTR=YPTR;
BPTR=XPTR;
}
}
else /*当前行不是虚拟行*/
{
if(BPTR->next==0) /*当前行指针BPTR指向正文链中最后一行*/
{
BPTR->next=YPTR;
YPTR->prior=BPTR;
BPTR=XPTR;
}
else /*BPTR指向正文链的中间某个结点*/
{
SPTR=BPTR->next;
BPTR->next=YPTR;
YPTR->prior=BPTR;
XPTR->next=SPTR;
SPTR->prior=XPTR;
BPTR=XPTR;
}
}
}
/*
#9 使BPTR指向虚拟行
*/
void TOP()
{
BPTR=0;
printf(" Move to virtual line successfully!");
}
/*
#10 进入输入模式
*/
void ENTER()
{
IND=1;
strcpy(IN,"INPUT! �");
WRITE_LINE();
}
/*
#11 使指针BPTR从当前行往上移N行,并且打印新的当前行
*/
void UP()
{
int GET_NUMBER();
if(GET_NUMBER()==1) /*不成功返回*/
return;
CTR=NUM; /*调用GET_NUMBER()得到的数在NUM中*/
if(TPTR==0)
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
if(BPTR==0)
{
strcpy(IN,"TOF!�");
WRITE_LINE();
return;
}
while(CTR>0)
{
BPTR=BPTR->prior;
CTR--;
if(BPTR==0)
{
strcpy(IN,"TOF!�");
WRITE_LINE();
return;
}
}
strcpy(IN,BPTR->str); /*打印当前行*/
WRITE_LINE();
}
/*
#12 从编辑命令中取来数N,把它存在缓冲器NUMD中。如果N是空格,则在CONVERT()中把补缺值置1
*/
int GET_NUMBER()
{
int l=0,xb,flag=0;
ERR=0;
if(IN[++i]!=' ')
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb=++i;
while(IN[xb]!='') /*计算正确命令从空格后第一个字符起到最后的字符长度l*/
{
xb++;
l++;
}
if(l>len) /*当字符长度l>4时,即输入的数字个数>4,认为命令出错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb=i;
while(IN[xb]!='')
{
if((IN[xb]<48||IN[xb]>57)&&IN[xb]!=' ') /*此命令输入的N中一旦出现既不是数字又不是空格的字符认为出错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb++;
}
xb=i;
while(IN[xb]!='') /*经过上面两个判断,N中为只包含数字和空格且长度<=4的字符,这里用来判断N中是否全为空格*/
{
if(IN[xb]!=' ')
{
flag=1;
break;
}
xb++;
}
if(!flag) /*全为空格,缺省值为*/
{
NUM=1;
return(0);
}
else
{
l=0;
while(IN[xb]!='')
{
if(IN[xb]>=48 && IN[xb]<=57)
NUMD[l++]=IN[xb];
else /*一旦出现数字,就要求N中一直到最后必须全为数字,否则认为出错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
xb++;
}
CONVERT(l);
}
if(ERR==1) /*ERR=1表示命令有错,发现错误后重置ERR=0,备以后判断*/
{
ERR=0;
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
else
return(0); /*成功返回*/
}
/*
#13 此模块把数组NUMD中用字符形式表示的十进制数转变成十进制数的内部表示形式,并存放到NUMD中
若NUMD中全是空格,则NUM中放1.如果NUM值为0,则把ERR置1以示错误,否则置0,表明转变成功
*/
void CONVERT(int l)
{
int m=0,dig;
NUM=0;
while(m<l)
{
dig=NUMD[m]-'0';
NUM=NUM*10+dig;
m++;
}
if(NUM==0)
ERR=1;
}
/*
#14 把指针BPTR从当前行往下移N行
*/
void NEXT()
{
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
{
BPTR=TPTR;
CTR--;
}
}
while(CTR>0)
{
if(BPTR->next==0)
{
strcpy(IN,"EOF!�");
WRITE_LINE();
return;
}
BPTR=BPTR->next;
CTR--;
}
strcpy(IN,BPTR->str);
WRITE_LINE();
}
/*
#15 输出正文链中从当前行开始的N行正文
*/
void LIST()
{
if(GET_NUMBER()==1)
return;
CTR=NUM; /*调用GET_NUMBER()得到的数在NUM中*/
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR; /*第一行作为当前行*/
}
strcpy(IN,BPTR->str);
CTR--;
WRITE_LINE();
while(CTR>0)
{
if(BPTR->next==0)
{
strcpy(IN,"EOF!�");
WRITE_LINE();
return;
}
BPTR=BPTR->next;
strcpy(IN,BPTR->str);
CTR--;
WRITE_LINE();
}
}
/*
#16 删掉正文链中从当前行开始的N行正文,并且释放后占的存贮空间,如果N是空格,则补缺值为1
*/
void DELETE()
{
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0)
{
if(TPTR==0)
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR;
}
DELETE_LINK();
while(YPTR!=XPTR) /*释放后占空间*/
{
YPTR=YPTR->next;
free(YPTR->prior);
}
free(XPTR);
printf(" delete successfully!");
}
/*
#17 从正文链中把要删掉的那些行分离下来。使YPTR和XPTR分别指向要被删掉的第一行和最后一行
*/
void DELETE_LINK()
{
YPTR=BPTR;
XPTR=BPTR;
CTR--;
while(CTR>0 && XPTR->next!=0)
{
XPTR=XPTR->next;
CTR--;
}
if(XPTR->next==0) /*已删到正文链末尾*/
{
if(CTR>0) /*要求删掉的行比能删掉的行多*/
{
strcpy(IN,"EOF!�");
WRITE_LINE();
}
if(YPTR->prior==0) /*从第一行开始删除*/
{
BPTR=0;
TPTR=0;
}
else /*还有正文链*/
{
BPTR=YPTR->prior;
BPTR->next=0;
}
}
else /*没有删到正文链末尾*/
{
BPTR=XPTR->next; /*BPTR指向被删掉的后面第一行,作为新的当前行*/
if(YPTR->prior==0)/*从第一行开始删*/
{
TPTR=BPTR;
TPTR->prior=0;
}
else /*从正文链的中间某个结点删,但是没有删到正文链末尾*/
{
SPTR=YPTR->prior;
SPTR->next=BPTR;
BPTR->prior=SPTR;
}
}
}
/*
#18 把正文链从当行开始的N行正文复制到工作链,这N行正文并不从正文链删除
思路:直接从正文链复制到工作链,当工作链空间不够用时提示用户输入了多少行
当复制的行数>可得到的行数,印出信息EOF
*/
void COPY()
{
int line=0;
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*无正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR; /*正文链第一行作为虚拟行*/
}
XPTR=BPTR;
while(CTR>0 && XPTR->next!=0)
{
if(KPTR==0) /*原来没有工作链*/
{
KPTR=(struct TEXT*)malloc(sizeof(struct TEXT));
if(!KPTR)
{
printf(" There is no free space!");
return;
}
work=KPTR;
KPTR->prior=0;
KPTR->next=0;
QPTR=KPTR;
strcpy(QPTR->str,XPTR->str);
XPTR=XPTR->next;
CTR--;
line++;
}
else /*已存在工作链*/
{
QPTR->next=(struct TEXT*)malloc(sizeof(struct TEXT));
if(!QPTR->next)
{
printf(" No free space,only copied %d lines!",line);
BPTR=XPTR;
return;
}
QPTR=QPTR->next;
QPTR->prior=work;
work=QPTR;
QPTR->next=0;
strcpy(QPTR->str,XPTR->str);
CTR--;
XPTR=XPTR->next;
line++;
}
}
if(XPTR->next==0)
{
if(CTR>0) /*退出上面的循环时最后一行尚未复制*/
{
BPTR=XPTR;
strcpy(IN,"EOF!�");
WRITE_LINE();
QPTR->next=(struct TEXT*)malloc(sizeof(struct TEXT));
if(!QPTR->next)
{
printf(" No free space,only copied %d lines!",line);
return;
}
QPTR=QPTR->next;
QPTR->prior=work;
work=QPTR;
QPTR->next=0;
strcpy(QPTR->str,XPTR->str);
CTR--;
XPTR=XPTR->next;
}
else
BPTR=XPTR;
}
else
BPTR=XPTR;
}
/*
#19 把正文链中从当前行开始的N行正文同其他正文分离开,然后把他们移到工作链的尾部。
调用Delete_Link()后,YPTR,XPTR分别指向要分离正文的第一行和最后一行。
*/
void STORE()
{
if(GET_NUMBER()==1)
return;
CTR=NUM;
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR; /*第一行作为当前行*/
}
DELETE_LINK();
if(KPTR==0)
{
KPTR=YPTR;
KPTR->prior=0;
}
else
{
QPTR->next=YPTR;
YPTR->prior=QPTR;
}
QPTR=XPTR;
work=QPTR;
QPTR->next=0;
}
/*
#20 把工作链中的全部正文都插到正文链中,紧接在当前行后面
*/
void INSERT()
{
if(KPTR==0)
{
printf(" There is no text in workspace!");
return;
}
printf(" INSERT SUCCESSFULLY!");
YPTR=KPTR;
XPTR=QPTR;
KPTR=0;
QPTR=0;
INSERT_CHAIN();
}
/*
#21 从命令中取得第一个字符串,并且把它存到缓冲器MAT中
*/
int GET_STRING1()
{
int j=0;
void WRITE_LINE();
if(IN[++i]!=' ') /*缓冲器IN中的第二个字符不是空格,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
if(IN[++i]!='/') /*缓冲器IN中的第三个字符不是斜线,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
if(IN[++i]=='/') /*空字符串,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
while(IN[i]!='' && IN[i]!='/') /*找到第二条斜线*/
MAT[j++]=IN[i++];
if(IN[i]=='') /*缺第二条斜线,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
i++; /*i指向第二条斜线后的第一个字符*/
MAT[j]='';
return(0);
}
/*
#22 这个模块比较缓冲器IN中从第I个字符开始的子字符串和缓冲器MAT中的字符串,开关CMP指示比较结果
1表示匹配,0表示不匹配
*/
void COMP()
{
int l,xb=0,up=0;
while(strlen(IN)-up>=strlen(MAT)) /*IN中剩余字符串的长度>MAT中的字符串长度,继续寻找*/
{
for(l=0;l<strlen(MAT);l++) temp[l]=IN[xb++]; /*temp是临时数组,存放IN中从第xb个字符起长度为strlen(MAT)的子串*/
temp[l]='';
if(strcmp(temp,MAT)==0) /*字符串匹配,CMP置1,返回*/
{
CMP=1;
return;
}
up++;
xb=up;
}
}
/*
#23 从当前行下面一行开始扫描正文链,使当前行指针指向第一次出现字符串STRING1的那一行
*/
void FIND()
{
if(GET_STRING1()==1) /*不成功返回*/
return;
if(TPTR==0) /*没有正文*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
if(BPTR==0)
BPTR=TPTR;
else
{
if(BPTR->next!=0) /*当前行不是正文链最后一行,从下一行开始扫描*/
BPTR=BPTR->next;
else
{
strcpy(IN,"EOF!�");
WRITE_LINE();
return;
}
}
while(BPTR->next!=0) /*逐行扫描*/
{
strcpy(IN,BPTR->str);
COMP();
if(CMP==1)
{
CMP=0;
WRITE_LINE();
return;
}
BPTR=BPTR->next;
}
strcpy(IN,BPTR->str); /*退出循环后,最后一行还没有扫描*/
COMP();
if(CMP==1)
{
CMP=0;
WRITE_LINE();
}
else
{
strcpy(IN,"EOF!�");
WRITE_LINE();
}
}
/*
#24 从编辑命令中取第二个字符串STRING2,开始时指针i指向第二条斜线的后的第一个字符。取得的字符串放在
缓冲器REP中
*/
int GET_STRING2()
{
int k=0;
if(IN[i]=='' || IN[i]=='/') /*缺第三条斜线或第二个字符串为空串*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
while(IN[i]!='/' && IN[i]!='')
REP[k++]=IN[i++];
if(IN[i]=='') /*IN中总是以�结束,如果以此条件退出循环,说明肯定没有第三条斜线,命令形式错*/
{
strcpy(IN,"?!�");
WRITE_LINE();
return(1);
}
REP[k]=''; /*成功找到第二个字符串*/
return(0);
}
/*
#25 在从当前行开始的N行正文中,每出现一个字符串STRING1,就用字符串STRING2来代替
*/
void REPLACE()
{
int xhbl,xj=0,sj=0;
struct TEXT *pre; /*PRE总是指向BPTR的前一个结点*/
if(GET_STRING1()==1)
{
strcpy(IN,"?!�");
WRITE_LINE();
return;
}
if(GET_STRING2()==1)
{
strcpy(IN,"?!�");
WRITE_LINE();
return;
}
if(GET_NUMBER()==1)
{
strcpy(IN,"?!�");
WRITE_LINE();
return;
}
if(BPTR==0) /*在虚拟行*/
{
if(TPTR==0) /*原来没有正文链*/
{
strcpy(IN,"NOTEXT!�");
WRITE_LINE();
return;
}
else
BPTR=TPTR;
}
CTR=NUM;
CHG=0;
while(CTR>0 && BPTR!=0)
{
strcpy(IN,BPTR->str);
while(strlen(IN)-xj>=strlen(MAT))/*检查机制:从IN第一个字符起,取长度为strlen(MAT)的子串放到temp中,和*/
{ /*MAT比较之后,再从IN第二个字符起,取长度为strlen(MAT)的子串放到temp中*/
for(xhbl=0;xhbl<strlen(MAT);xhbl++)temp[xhbl]=IN[sj++];
temp[xhbl]='';
if(strcmp(temp,MAT)==0)
{
CHG=1;
BACK(xj,sj);
sj+=strlen(REP)-strlen(MAT); /*替换后,从替换后的下一个字符起检查串有无其它和MAT相同的子中*/
xj=sj;
continue;
}
xj++;
sj=xj;
}
if(CHG==1)
{
CHG=0;
strcpy(BPTR->str,IN);
WRITE_LINE();
}
pre=BPTR;
BPTR=BPTR->next;
CTR--;
xj=0; /*sj,xj重置初值,扫描下一行*/
sj=0;
}
if(BPTR==0) /*若出现要求代替的行数多于能得到的行数,显示信息EOF!*/
if(CTR>0)
{
strcpy(IN,"EOF!�");
WRITE_LINE();
}
BPTR=pre;
}
/*
#26 此模块用来完成替换
up指向IN中一子串的首地址,此子串与MAT匹配,xb指向此子串的后面的第一个字符
*/
void BACK(int up,int xb)
{
int sub,len1,len2,leftspa,j=0,l;
len1=strlen(MAT);
len2=strlen(REP);
sub=len2-len1; /*求出用REP中替换IN中的子串后增加了几个字符,可能为负数*/
leftspa=LINESIZE-strlen(IN); /*求IN中的剩余空间*/
if(len1==len2) /*要替换的串与被替换的串长度相等*/
for(l=1;l<=len2;l++)
IN[up++]=REP[j++]; /*从up位置起逐个替换原子串*/
if(len1>len2)
{
for(l=1;l<=len2;l++)
IN[up++]=REP[j++];
up=xb-up; /*求xb到up之间用几个字符*/
while(IN[xb]!='')
{
IN[xb-up]=IN[xb]; /*从xb位置起逐个后移字符,位移量为up*/
xb++;
}
IN[xb-up]='';
}
if(len1<len2)
{
if(leftspa>=sub) /*IN中剩余空间大于等于要增加的字符,此时空间够用*/
{
for(l=strlen(IN);l>=xb;l--)
IN[l+sub]=IN[l]; /*从�起逐个后移字符,腾出空间*/
for(l=1;l<=len2;l++)
IN[up++]=REP[j++]; /*空间已腾出,逐个替换即可*/
}
else /*IN中空间小于要增加的字符数,需进行截尾操作*/
{
for(l=strlen(IN)-(sub-leftspa)-1;l>=xb;l--) /*算出需截掉的字符个数为sub-leftspa,
IN[l+sub]=IN[l]; /*只需从strlen(IN)-(sub-leftspa)-1开始逐个后移字符*/
IN[LINESIZE]='';
for(l=1;l<=len2 && l<LINESIZE-up;l++) /*逐个替换需保证循环次数,只能从up到�之间*/
IN[up++]=REP[j++];
}
}
}
/*
ex: 显示帮助!
*/
void HELP()
{
printf(" _______________________________________________________________");
printf(" | ShitNotepad HELP |");
printf(" ---------------------------------------------------------------");
printf(" | Input T to the TOP |");
printf(" | Input U n to UP n line |");
printf(" | Input N n to NEXT n line |");
printf(" | Input E to ENTER |");
printf(" | Input R /STR1/STR2/ n to REPLACE a word in line n |");
printf(" | Input C n to COPY line n |");
printf(" | Input L n to LIST line n |");
printf(" | Input F /SFTR1/ to FIND a word in line n |");
printf(" | Input S n to STORE line n |");
printf(" | Input D n to DELETE line n |");
printf(" | Input I to INSERT |");
printf(" | Input Q to QUIT |");
printf(" | Input H for the Help |");
printf(" ---------------------------------------------------------------");
}
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>
#include <dos.h>
// TODO: reference additional headers your program requires here
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>
#include <dos.h>
// TODO: reference additional headers your program requires here
- 北京信息工程学院、北京信息科技大学 软件工程课程设计全部代码,希望对北信的下一代有用!
- 在北京信息科技大学的发言
- 北京信息科技大学CSDN高校俱乐部举办的首次活动------考研经验交流会
- 北京信息科技大学CSDN高校俱乐部运营策划
- 北京信息科技大学CSDN俱乐部第一次招新
- 今天在北京出差,时代亿信的一个门户项目,希望周日能结束
- 北京星兆老年病医院的希望
- 北京周遍的温泉信息
- 来北京,是对的
- 北京信息科技大学校赛(全部题解)
- 就北京来说,有对 PM2.5 有用的空气净化器么?
- 北京
- 北京
- 北京
- 北京
- 北京
- 北京
- 北京出租车计费的信息与分析
- ResEdit 1.3.6
- 银行自助设备详细介绍(四)——存款机
- 公司是技术人员还是市场人员更重要?
- 在login.sql文件中设置sql*plus的环境(摘自《Oracle编程艺术》)
- 智能设备 C#调用MFC DLL 传参值为汉字的解决方案 CString转存 unsigned char数组
- 北京信息工程学院、北京信息科技大学 软件工程课程设计全部代码,希望对北信的下一代有用!
- VC中使用SCRIPT 正则写的LRC歌词分析类
- HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth之完全详解
- 摩羯
- 运算符++的奥秘
- 程序员
- 加密狗
- 60秒出口才
- 程序员真实写真35岁前成功的12条黄金法则.doc