int allrec; // 编辑记录行数
int scry; // 屏幕首条记录在整个文件中的位置, 取值范围[0..allrec-1] int shinex, shiney; // 光标所在行坐标 shinex:[1..MAXCOL] shiney:[1..24] unsigned char info[MAXROW][MAXCOL+1]; // 编辑文件内容
}EDIT; EDIT edit;
void main( int argc, char *argv[] ) { if( argc != 2 ) { printf( \ return; }
if( init(argv[1]) < 0 ) // 初始化失败 return;
editfun( argv[1] ); clrscr(); // 清屏
exit( 0 );
}
int init( char *filename ) // 系统初始化 返回0: 成功 -1:出错 { int i, j; FILE *fp; if( (fp=fopen(filename,\ printf( \st! Create now!\\n\ if( (fp=fopen(filename,\w\ printf( \, filename ); return -1; }
fprintf( fp, \// 加入一空行 fclose( fp ); // 创建一个空文件
fp = fopen( filename , \
}
memset( edit.info, 0, sizeof(edit.info) ); // 将编辑缓冲区清0 for( i = 0 ; i < MAXROW ; i++ ) { fgets( edit.info[i], MAXCOL + 1 , fp ); if( feof(fp) ) // 文件尾 break; j = strlen( edit.info[i] ) - 1;
if( edit.info[i][j] == '\\n' ) //删除换行符
80
edit.info[i][j] = '\\0'; }
edit.allrec = i; edit.scry = 0; edit.shinex = 1; edit.shiney = 1; fclose( fp ); return 0;
}
int editfun( char *filename ) // 全屏幕编辑主函数, 返回0:存盘返回 { int editflag=0; // 处理方式 0: 命令方式 1: 编辑方式 int nr; // 编辑记录行号 int i;
int in_ch; // 键盘输入字符的值 int cmdtimes; // 命令执行次数 int rolllines; // 屏幕滚动行数 int len; // 当前编辑行内容长度 char command[81]; // 命令行缓冲区 char queryinfo[81]; // 查找字符缓冲区 refresh_scr(); // 输出编辑内容 memset( queryinfo, 0, sizeof(queryinfo) ); while( 1 ) { if( editflag == 1 && edit.allrec == 0 ) // 编辑状态下,至少有一空行 edit.allrec = 1; if( edit.shiney + edit.scry > edit.allrec ) // 最后一页的最大可编辑行号
edit.shiney = edit.allrec - edit.scry;
nr = edit.shiney - 1 + edit.scry; // 当前编辑列,即edit.info的下标 len = strlen( edit.info[nr] ); if( edit.shinex >= len + 1 )
// 光标所在位置X轴坐标
edit.shinex = ( editflag==1 || len==0 ) ? len + 1 : len; gotoxy( edit.shinex, edit.shiney ); // 移动光标 in_ch = getch(); // 从键盘接收一个字符,不回显 if( editflag ) { // 编辑方式 switch( in_ch ) { case ESC: // ESC 表示一次输入的结束
editflag = 0;
if( edit.shinex > 1 )
81
edit.shinex--; // 光标左移一格
break; case BackSpace: // 退格键,表示删除一个字符 if( edit.shinex > 1 ) { // 有字符可以删除 for( i = edit.shinex-1; i< MAXCOL-1; i++ ) // 数据前移一个字节
edit.info[nr][i] = edit.info[nr][i+1];
if( edit.shinex > 1 )
edit.shinex--; // 光标左移一格
display( edit.shiney, edit.info[nr] ); // 刷新该行 } break; case CR: // 回车表示要编辑下一行 append(); break;
default: // 其他情况表示输入一个字符 for( i = MAXCOL - 1; i >= edit.shinex; i-- ) // 数据后移一字节
edit.info[nr][i] = edit.info[nr][i-1];
edit.info[nr][i] = (unsigned char)in_ch; if( edit.shinex < MAXCOL ) edit.shinex++; // 光标右移一格
display( edit.shiney, edit.info[nr] ); // 刷新该行
break;
} } else { // 命令方式
memset( command, 0, sizeof(command) ); cmdtimes = 1; // 命令执行次数缺省为1
if( in_ch >= '1' && in_ch <= '9' ) { // 输入数字,表示重复执行命令 for( i = 0; in_ch >= '0' && in_ch <= '9' ; i++ ) { command[i] = (char)in_ch; in_ch = getch(); }
cmdtimes = atoi( command ); // 命令执行次数
if( cmdtimes <= 0 || cmdtimes >= MAXCMDTIMES ) { // 输入越界 beep();
continue;
} }
if( in_ch == 0 )// 按功能键←,↑,→,↓,PgUp, PgDn时,会产生组合键
in_ch = getch();
82
switch( in_ch ) { case 'i': // 在光标所在位置的前面插入文本
editflag = 1; // 进入编辑状态
break;
case 'a': // 在光标所在位置的后面插入文本 edit.shinex++; editflag = 1; // 进入编辑状态 break;
case 'A': // 在光标所在行的末尾插入文本
edit.shinex = len + 1; editflag = 1; // 进入编辑状态 break; case 'o': // 在光标的下一行插入一空行 append(); // 加一空行 editflag = 1; // 进入编辑状态 break; case ':': gotoxy( 1, 25 );
clreol(); // 清除提示行
printf( \
if( input_str(2,25,command,sizeof(command)-1) == 0 ) {// 输入正确 if( strcmp(command,\) == 0 ){ // 存盘退出 write_file( filename );
return 0;
}
if( strcmp(command,\) == 0 ) // 放弃退出 return 1;
if( strcmp(command,\w\
// 存盘
write_file( filename );
} break;
case '/':
// 向后搜索
gotoxy( 1, 25 ); clreol(); clreol(); // 清除提示行 printf( \
if( input_str(2,25,command,sizeof(command)-1) == 0 ) // 输入正确 strcpy( queryinfo, command ); else // 输入错误,不查找
break;
83