《数据结构实验与实训教程(第4版)》程序代码 下载本文

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