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. 思 ...
随机推荐
- WebLogic配置与部署
一.创建域: 第一步,选择“开始菜单”-> “Oracle WebLogic”-> “WebLogic Server 10gR3” -> “Tools”-> “Configur ...
- asyncio标准库3 HTTP client example
import aiohttp import asyncio import async_timeout async def fetch(session, url): async with async_t ...
- hadoop使用
hadoop@ubuntu:~$ cd hadoop-2.0.5-alpha/ hadoop@ubuntu:~/hadoop-2.0.5-alpha$ ls hadoop@ubuntu:~/hadoo ...
- 【Leetcode】【Easy】Add Binary
Given two binary strings, return their sum (also a binary string). For example,a = "11"b = ...
- 团队的初体验与Scrum的初识
一. 队名及宣言 队名: the better for you 宣言: Change our lives with code 二. 队员及分工 a.承担软件工程的角色 姓名 学号 角色 蒋 婷 B20 ...
- Catalan数列
引入 今天听学长讲了卡特兰数列后对其有了更深的认识,在此完善了一下之前的博客加以总结. 首先用一个经典的例子来描述一下Catalan数列,我们有一个1~n的数列和一个大小为n的栈,我们有如下两种操作: ...
- 【转】Android应用程序窗口(Activity)窗口对象(Window)创建指南
在前文中,我们分析了Android应用程序窗口的运行上下文环境的创建过程.由此可知,每一个Activity组件都有一个关联的ContextImpl对象,同时,它还关联有一个Window对象,用来描述一 ...
- ACM-ICPC 2017 Asia Xi'an J LOL 【暴力 && 排列组合】
任意门:https://nanti.jisuanke.com/t/20750 J - LOL 5 friends play LOL together . Every one should BAN on ...
- 2018.11.13 Hibernate 中数据库查询中的Criteria查询实例
Criteria是面向对象的无语句查询 Demo.java package com.legend.b_criteria; import java.util.List; import org.hiber ...
- Android学习笔记_24_多媒体MediaPlayer对象之音乐播放器与SoundPool声音池
一.MediaPlayer对象常用方法介绍: MediaPlayer mediaPlayer = new MediaPlayer(); if (mediaPlayer.isPlaying()) { m ...