实例说明:

  编辑一个简单的单行文本编辑器,编辑命令有以下几种:(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. C语言学习之第一个程序

    #include<stdio.h> int main() { printf("This is my first program!\n"); ; } 基本格式大致如下: ...

  2. tensorflow 模型不兼容

    [ERROR] [1533570199.196157]: bad callback: <bound method TLDetector.image_cb of <__main__.TLDe ...

  3. 时间序列算法理论及python实现(1-算法理论部分)

    如果你在寻找时间序列是什么?如何实现时间序列?那么请看这篇博客,将以通俗易懂的语言,全面的阐述时间序列及其python实现. 就餐饮企业而言,经常会碰到如下问题. 由于餐饮行业是胜场和销售同时进行的, ...

  4. oracle数据库中创建表空间和临时表空间,以及用户和密码以及设置密码永不过期

    首先进入oracle用户,命令是: su - oracle sqlplus /nolog connect system/123456@ora11g 或者 [oracle@localhost ~]$   ...

  5. Java里面String的编码问题

    Java里面内置字符串全部是utf-16编码,详细的编码方式看这里 import java.nio.charset.Charset; import java.util.Arrays; import j ...

  6. BestCoder Round #81 (div.2)

    HDU:5670~5764 A题: 是一个3进制计数: #include <bits/stdc++.h> using namespace std; ]; int calc(long lon ...

  7. HDU 5687 Problem C 【字典树删除】

    传..传送:http://acm.hdu.edu.cn/showproblem.php?pid=5687 Problem C Time Limit: 2000/1000 MS (Java/Others ...

  8. MVC学习二:Controller和View关系

    控制器(Controller)主要是定义方法和加载视图(View) 1.控制器中的Action方法返回值的类型ActionResult,string 2.控制器中Action方法接收浏览器参数方式: ...

  9. 【luogu P3385 负环】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3385 SPFA判负环. 这个题必须卡一卡才过得去. 按理说对于一个负环点应当是入队 > n次. 但是这 ...

  10. linux多线程编程基本操作(2)

    linux c多线程总结: :关于线程和进程 a:使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式.我们知道,在Linux系统下,启动一个新的进程必须分配给 ...