实例说明:

  编辑一个简单的单行文本编辑器,编辑命令有以下几种:(E、Q、R、I、D)

只有自己在完全空白的情况下编写出来的程序,才是真正自己会的程序,现在所做的,不过是程序的搬运工,把书上的程序搬到网上,不过是添加了几句注释而已。

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAXLEN 80 //所处理文本一行最大字符个数
#define MAXLINE 200 //所处理文本最大行数 char buffer[MAXLEN]; //用来存储命令行输入的命令,以及命令所带的参数
char fname[]; //用来存储所处理文件的文件名
char *lineptr[MAXLINE]; //行指针
FILE *fp; //文件指针
void edit(),replace(),insert(),delete(),quit(); //函数声明,具体的函数定义在后面
char comch[] = "EeRrIiDdQq"; //命令符
void(*comfun[])() = {edit,replace,insert,delete,quit}; //对应处理函数
int modified=; //正文修改标志
int last; //当前正文行数
char *chpt; //输入命令行字符指针 int main()
{
int j;
last = ; while()
{
printf("\nInput a command:[e,r,i,d,q].\n");
gets(buffer); //读入命令行
for(chpt=buffer; *chpt==' '||*chpt=='\t'; chpt++); //掠过空白符
if(*chpt=='\0') continue; //空行重新输入
for(j=; comch[j]!='\0'&&comch[j]!=*chpt; j++); //查找命令符对应的处理函数
if(comch[j]=='\0') continue; //非法命令符
chpt++; //掠过命令符,指向参数
(*comfun[j/])(); //执行对应的函数
fprintf(stdout,"The text is :\n");
for(j=; j<last; j++) //显示正文文本
fputs(lineptr[j],stdout);
}
return ;
} //====================================================================================
//函数名称:void quit()
//函数功能:结束编辑
//对应命令:q/Q
//入口参数:无
//出口参数:无
//====================================================================================
void quit()
{
int c;
if(modified) //判断正文是否被修改
{
printf("Save?(y/n)");
while(!(((c=getchar())>='a'&&c<='z')||(c>='A'&&c<='Z'))); //判断输入是否为合法字符
if(c=='y'||c=='Y')
save(fname);
}
for(c=; c<last; c++)
free(lineptr[c]); //释放内存
exit();
} //====================================================================================
//函数名称:void insert()
//函数功能:将I/i命令后继的K行文本插入到原始正文第M行之后
//入口参数:无
//出口参数:无
//命令格式:
//I K M
//K行正文
//====================================================================================
void insert()
{
int k,m,i;
sscanf(chpt, "%d%d", &k, &m);
if(m<||m>last||last+k>=MAXLINE) //判断插入文本位置是否正确
{
printf("Error!\n");
return;
}
for(i=last; i>m; i--) //后继行向后移
lineptr[i+k-] = lineptr[i-];
for(i=; i<k; i++) //读入k行正文,并插入
{
fgets(buffer, MAXLEN, stdin);
lineptr[m+i] = (char *)malloc(strlen(buffer)+);
strcpy(lineptr[m+],buffer);
}
last += k; //修改正文行数
modified = ; //标明正文已被修改
} //====================================================================================
//函数名称:void delete()
//函数功能:将原始正文中第M行至第N行的正文内容删去
//入口参数:无
//出口参数:无
//命令格式:
//D M N
//====================================================================================
void delete()
{
int i,j,m,n;
sscanf(chpt, "%d%d", &m,&n);
if(m<=||m>last||n<m) //检查参数合理性
{
printf("Error!\n");
return;
}
if(n>last)
n = last; //修正参数
for(i=m; i<=n; i++) //删除正文
free(lineptr[i-]);
for(i=m,j<n+; j<=last; i++,j++) //将原文的N行之后的文本前移
lineptr[i-] = lineptr[j-];
last = i-;
modified = ;
} //====================================================================================
//函数名称:void replace()
//函数功能:用R命令后继的K行正文替代原始正文中的M行到N行的正文内容
//入口参数:无
//出口参数:无
//命令格式:
//R K M N
//K行正文
//====================================================================================
void replace()
{
int k,m,n,i,j;
sscanf(chpt,"%d%d%d",&k,&m,&n); /* 读入参数 */
if(m<=||m>last||n<m||last-(n-m+)+k>=MAXLINE) /* 检查参数合理性 */
{
printf("Error!\n");
return;
}
/* 先完成删除 */
if(n>last)
n=last; /* 修正参数 */
for(i=m;i<=n;i++) /* 删除正文 */
free(lineptr[i-]);
for(i=m,j=n+;j<=last;i++,j++) //文本前移
lineptr[i-]=lineptr[j-];
last=i-;
/* 以下完成插入 */
for(i=last;i>=m;i--)
lineptr[i+k-]=lineptr[i-];
for(i=;i<k;i++)
{
fgets(buffer,MAXLEN,stdin);
lineptr[m+i-]=(char *)malloc(strlen(buffer)+);
strcpy(lineptr[m+i-],buffer);
}
last+=k; /* 修正正文行数 */
modified=; /* 正文被修改 */
} //====================================================================================
//函数名称:void save(char *fname)
//函数功能:用来保存文本
//入口参数:char *fname
//出口参数:无
//====================================================================================
void save(char *fname) /* 保存文件 */
{
int i;
FILE *fp;
if((fp=fopen(fname,"w"))==NULL)
{
fprintf(stderr,"Can't open %s.\n",fname);
exit();
}
for(i=;i<last;i++)
{
fputs(lineptr[i],fp);
free(lineptr[i]);
}
fclose(fp);
} //====================================================================================
//函数名称:void edit()
//函数功能:指定所要编辑的文本
//入口参数:无
//出口参数:无
//====================================================================================
void edit() /* 编辑命令 */
{
int i;
FILE *fp;
i=sscanf(chpt,"%s",fname); /* 读入文件名 */
if(i!=)
{
printf("Enter file name.\n");
scanf("%s",fname);
}
if((fp=fopen(fname,"r"))==NULL) /* 读打开 */
{
fp=fopen(fname,"w"); /* 如不存在,则创建文件 */
fclose(fp);
fp=fopen(fname,"r"); /* 重新读打开 */
}
i=;
while(fgets(buffer,MAXLEN,fp)==buffer)
{
lineptr[i]=(char *)malloc(strlen(buffer)+);
strcpy(lineptr[i++],buffer);
}
fclose(fp);
last=i;
}

C语言实例解析精粹学习笔记——39(简单的文本编辑器)的更多相关文章

  1. C语言实例解析精粹学习笔记——18

    <C语言实例解析精粹>中编译环境采用的是Turbo C 2.0.但是这个编译器年代久远,较新的编译器对书中的某些例子支持不好,在学习的时候同时做一些笔记. 实例18:将一个无符号整数转换为 ...

  2. C语言实例解析精粹学习笔记——35(报数游戏)

    实例35: 设由n个人站成一圈,分别被编号1,2,3,4,……,n.第一个人从1开始报数,每报数位m的人被从圈中推测,其后的人再次从1开始报数,重复上述过程,直至所有人都从圈中退出. 实例解析: 用链 ...

  3. C语言实例解析精粹学习笔记——42(插入排序)

    实例说明: 将一个整数数组按从小到大的顺序进行排序.(主要学习基本的插入排序和改进的冒泡排序的算法和应用) 思路1: 从第一个数据开始,分别比较其后的数据,若比它小,则将这两个数的位置交换:从第一个数 ...

  4. C语言实例解析精粹学习笔记——36(模拟社会关系)

    实例: 设计一个模拟社会关系的数据结构,每个人的信息用结构表示,包含名字.性别和指向父亲.母亲.配偶.子女的指针(只限两个子女).要求编写以下函数: (1)增加一个新人的函数 (2)建立人与人之间关系 ...

  5. C语言实例解析精粹学习笔记——34(用“结构”统计学生成绩)

    实例34: 设学生信息包括学号.姓名和五门功课的成绩,要求编写输入输出学生信息的函数.在输入学生信息后,以学生成绩的总分从高到低顺序输出学生信息. 思路: 程序引入一个结构数组依次存储输入的学生信息, ...

  6. C语言实例解析精粹学习笔记——32

    实例32: 编制一个包含姓名.地址.邮编和电话的通讯录输入和输出函数. 思路解析: 1.用结构体来完成姓名.地址.邮编和电话的组合. 2.结构体指针的使用. 3.malloc的使用 4.scanf函数 ...

  7. C语言实例解析精粹学习笔记——31

    实例31: 判断字符串是否是回文 思路解析: 引入两个指针变量(head和tail),开始时,两指针分别指向字符串的首末字符,当两指针所指字符相等时,两指针分别向后和向前移动一个字符位置,并继续比较, ...

  8. C语言实例解析精粹学习笔记——30

    实例30: 用已知字符串s中的字符,生成由其中n个字符组成的所有字符排列.设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次.例如,对于s[]="abc",n=2, ...

  9. C语言实例解析精粹学习笔记——28

    实例28:从键盘读入实数 题目要求: 编制一个从键盘读入实数的函数readreal(double *rp).函数将读入的实数字符列转换成实数后,利用指针参数rp,将实数存于指针所指向的变量*rp. 思 ...

随机推荐

  1. Linux--DHCP搭建

    服务功能:为局域网中的主机自动分配IP地址.子网掩码.广播地址.默认网关地址.DNS服务器地址 1.安装DHCP服务器软件 [root@localhost Packages]# rpm -ivh dh ...

  2. 使用sqlloader向oracle导入文本数据

    文本文件如下,注意文件名必须有后缀,文本行首也需要|分隔符:[oracle@ycr test]$ more person.txt|aaa|123|m|aaa|123|m|aaa|123|m|aaa|1 ...

  3. Smart template的控件能否当成普通控件来用

    我的同事问过我这个问题: 只要弄清楚Smart control的原理,就能回答这个问题. 答案是: smart control可以像普通的控件一样在xml view中被定义和使用,但是必须结合ODat ...

  4. LeetCodeOJ刷题之14【Longest Common Prefix】

    Longest Common Prefix Write a function to find the longest common prefix string amongst an array of ...

  5. IOS 集成友盟分享

    #import <Foundation/Foundation.h> @interface UMSocialSinaHandler : NSObject +(void)openSSOWith ...

  6. ubuntu误删home目录

    今天第一次写shell脚本,一不小心把home目录全给删除了. 解决方案: 先把手打上二十大板!!! [root@myshell ~]#mkdir /home/test01             / ...

  7. 【[NOI2003]文本编辑器】

    题目 发现这样一句话就会导致\(T\) ch[m][0]=++m; 并不是很知道为什么,可能这是某种未定义行为在不同编译器下会有不同后果? 至于这道题就很简单了,几个有关光标位置的操作就用一个变量模拟 ...

  8. 深入 Struts2 的配置 - 处理多个请求-处理请求结果-模型驱动-异常机制

    转:http://www.java3z.com/cwbwebhome/article/article2/2938.html?id=1631 本部分主要介绍struts.xml的常用配置. 1.1.   ...

  9. Extjs 4.2 panel 添加 click 事件及右键菜单

    listeners: { render: function(c) { c.body.on('click', function() { //TODO 添加点击事件功能 }); c.body.on('co ...

  10. o'Reill的SVG精髓(第二版)学习笔记——第五章

    第五章 文档结构 5.1 结构与表现 XML的目标之一便是提供一种能将结构从视觉表示中独立出来的方法. 但是不幸的是,关于XML的很多讨论都强调结构而非表现. 我们将通过详细讨论如何在SVG中指定表现 ...