C语言实例解析精粹学习笔记——39(简单的文本编辑器)
实例说明:
编辑一个简单的单行文本编辑器,编辑命令有以下几种:(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(简单的文本编辑器)的更多相关文章
- C语言实例解析精粹学习笔记——18
<C语言实例解析精粹>中编译环境采用的是Turbo C 2.0.但是这个编译器年代久远,较新的编译器对书中的某些例子支持不好,在学习的时候同时做一些笔记. 实例18:将一个无符号整数转换为 ...
- C语言实例解析精粹学习笔记——35(报数游戏)
实例35: 设由n个人站成一圈,分别被编号1,2,3,4,……,n.第一个人从1开始报数,每报数位m的人被从圈中推测,其后的人再次从1开始报数,重复上述过程,直至所有人都从圈中退出. 实例解析: 用链 ...
- C语言实例解析精粹学习笔记——42(插入排序)
实例说明: 将一个整数数组按从小到大的顺序进行排序.(主要学习基本的插入排序和改进的冒泡排序的算法和应用) 思路1: 从第一个数据开始,分别比较其后的数据,若比它小,则将这两个数的位置交换:从第一个数 ...
- C语言实例解析精粹学习笔记——36(模拟社会关系)
实例: 设计一个模拟社会关系的数据结构,每个人的信息用结构表示,包含名字.性别和指向父亲.母亲.配偶.子女的指针(只限两个子女).要求编写以下函数: (1)增加一个新人的函数 (2)建立人与人之间关系 ...
- C语言实例解析精粹学习笔记——34(用“结构”统计学生成绩)
实例34: 设学生信息包括学号.姓名和五门功课的成绩,要求编写输入输出学生信息的函数.在输入学生信息后,以学生成绩的总分从高到低顺序输出学生信息. 思路: 程序引入一个结构数组依次存储输入的学生信息, ...
- C语言实例解析精粹学习笔记——32
实例32: 编制一个包含姓名.地址.邮编和电话的通讯录输入和输出函数. 思路解析: 1.用结构体来完成姓名.地址.邮编和电话的组合. 2.结构体指针的使用. 3.malloc的使用 4.scanf函数 ...
- C语言实例解析精粹学习笔记——31
实例31: 判断字符串是否是回文 思路解析: 引入两个指针变量(head和tail),开始时,两指针分别指向字符串的首末字符,当两指针所指字符相等时,两指针分别向后和向前移动一个字符位置,并继续比较, ...
- C语言实例解析精粹学习笔记——30
实例30: 用已知字符串s中的字符,生成由其中n个字符组成的所有字符排列.设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次.例如,对于s[]="abc",n=2, ...
- C语言实例解析精粹学习笔记——28
实例28:从键盘读入实数 题目要求: 编制一个从键盘读入实数的函数readreal(double *rp).函数将读入的实数字符列转换成实数后,利用指针参数rp,将实数存于指针所指向的变量*rp. 思 ...
随机推荐
- Azure进阶攻略丨共享访问签名是个什么东东?
Azure 进阶攻略]一经推出便受到了广大粉丝的热情追捧,大家纷纷表示涨了姿势,并希望能了解更多的攻略~根据大家的投票结果,本期,小编将为大家讲解“如何生成 Shared Access Signatu ...
- Angular 5.x 学习笔记(1) - 模板语法
Angular 5.x Template Syntax Learn Note Angular 5.x 模板语法学习笔记 标签(空格分隔): Angular Note on github.com 上手 ...
- css随笔
1. 关于使用pre标签,且要自动换行 可以使用: word-wrap: break-word; white-space: pre-wrap; 2. 更改placeholder样式 .input::- ...
- msysGit删除github文件
首先打开msysGit命令行工具 首先使用命令 git rm xxx 删除远程文件 提交删除操作 git commit -m "test" ,并推送到远程仓库 git push o ...
- 每天一个linux命令(22):tar命令
通过SSH访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候tar命令就是是必不可少的一个功能强大的工具.linux中最流行的tar是麻雀虽小,五脏俱全,功能强大. tar命令可以为linux ...
- 布局方式-inline-block布局
.像文本一样排block元素 .没有清除浮动等问题 .需要处理间隙 一种方式 <style> .container{ width: 800px; height: 200px; fo ...
- luogu P1503 鬼子进村
嘟嘟嘟 线段树好题. 其实挺水的,想暴力怎么做:每一次从这个点开始向两边扩,直到遇到第一个摧毁的房屋. 那么把暴力改成倍增,然后线段树查询区间和是否为0.时间复杂度O(nlog2n). 题解好像有线段 ...
- 2018.11.21 struts2获得servletAPI方式及如何获得参数
访问servletAPI方式 第一种:通过ActionContext (重点及常用 都是获得原生对象) 原理 Action配置 被引入的配置文件 在页面调用取值 第二种:通过ServletAction ...
- python time模块计算程序耗时
import time start = time.clock() end = time.clock() consume_time = end - start
- 整个ssd的网络和multibox_loss_layer
总结说来prior_box层只完成了一个提取anchor的过程,其他与gt的match,筛选正负样本比例都是在multibox_loss_layer完成的 http://www.360doc.com/ ...