📄 z_file.c
字号:
# include <stdio.h># include <curses.h># include <signal.h># include <sys/time.h># define SMON_ITV 1 /* 屏幕监控时间间隔 */# define L 256 /* 每行最大长度 */static int BL, /* (表头除外)屏幕显示起始行 */ N, /* (表头除外)屏幕显示行数 */ Pages = 0, /* 显示信息共多少屏 */ scrs = 0, /* 当前屏幕序号,从 0开始 */ t_esc = 0; /* <Esc>按键次数 *//****** 空函数 ******/static void z_f_empty(int sig) {}/********** 初始化屏幕 **********/void z_initscr(void){ initscr(); noecho(); curs_set(0); keypad(stdscr, TRUE);}/************ 结束屏幕处理 ************/void z_endwin(void){ addstr(" "); refresh(); clear(); refresh(); endwin();}/****************** 结束屏幕处理,退出 ******************/static void z_win_exit(int sig){ z_endwin(); exit(0);}/************************** 文件是否还有未显示的数据行 **************************/static int z_more_lines(FILE *pfp, long *n){ char buf[L + 1]; int i, rows; i = 0; rows = scrs * N; rewind(pfp); while( ! feof(pfp) ) { memset(buf, 0, L + 1); if( fgets(buf, L, pfp) == NULL ) break; if( (++i) > rows ) return(1); (*n) += strlen(buf); } return(0);}/************ 显示一屏内容 ************/static int z_putstr(FILE *pfp){ int i, y, x; char buf[L + 1], tms[20], pg[25]; x = 0; y = BL; z_get_dt(tms, 19, "l", 0); sprintf(pg, "P: %d/%d", scrs + 1, Pages); move(y, 0); clrtobot(); standout(); mvaddstr(lines - 1, 0, "连续两次<Esc>键退出,↓↑翻屏"); standend(); clrtoeol(); mvprintw(lines - 1, 40, "%s %21s", tms + 5, pg); for(i = 0; i < N; i++ ) { memset(buf, 0, L + 1); if( fgets(buf, L, pfp) == NULL ) break; mvaddstr(y, x, buf); y++; } refresh(); return(0);}/**************************** 文件显示(需要事先初始化屏幕) ****************************/int z_disscr(char *filename, char *phead){ FILE *fp; char *p, v[L + 1]; long offset; int f_show, ch, i, n, b, flines; ch = 0; if( (fp = fopen(filename, "r")) == NULL ) { standout(); mvprintw(1, 0, "打开文件 %s 错误! 请检查目录设置及文件权限", filename); standend(); refresh(); sleep(3); return(-1); } /* 显示表头 */ i = 0; if( phead != NULL && *phead ) { p = phead; do { n = 0; memset(v, 0, L + 1); b = z_get_fieldv(&p, v, &n, L, "\n"); mvaddstr(i, 0, v); if( (++i) > (lines - 3) ) break; /* 为正文与提示行预留版面 */ } while ( b ); } BL = i; N = lines - 1 - i; /* 统计文件行数 */ if( (flines = z_filelines(filename)) < 0 ) return(-1); /* 计算屏幕 */ Pages = flines / N; if( flines % N ) Pages ++; offset = 0; z_more_lines(fp, &offset); fseek(fp, offset, 0); z_putstr(fp); while( 1 ) { mvprintw(lines - 1, 30, "%c", '.'); flushinp(); ch = getch(); if( ch == 27 ) { /*两次<Esc>键退出*/ if( t_esc == 1 ) { fclose(fp); return(-1); } else t_esc = 1; } else t_esc = 0; f_show = 1; if( ch != -1 ) offset = 0; switch (ch) { case 66: case 69: case 10: case 32: case KEY_DOWN: case KEY_RIGHT: /*下翻一屏*/ scrs ++; if( z_more_lines(fp, &offset) == 0 ) { scrs --; f_show = 0; } break; case KEY_UP: case KEY_LEFT: /*上翻一屏*/ case 67: case 68: if( scrs ) { scrs --; if( z_more_lines(fp, &offset) == 0 ) f_show = 0; } else f_show = 0; break; case -1: /*被定时信号中断*/ fclose(fp); return(0); default: f_show = 0; } if( f_show ) { fseek(fp, offset, 0); z_putstr(fp); } } fclose(fp); return(0);}/************ 设定信号处理 ************/static void z_sig_refresh(void){ struct sigaction sa; memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = SIG_IGN; sigaction(SIGINT, &sa, NULL); sigaction(SIGQUIT, &sa, NULL); sa.sa_handler = z_win_exit; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = z_f_empty; sigaction(SIGALRM, &sa, NULL);}/************ 设定刷新时间 ************/void z_set_refresh(int sec, int usec){ struct itimerval rttimer; z_sig_refresh(); /* 设定定时间隔 */ rttimer.it_value.tv_sec = sec; rttimer.it_value.tv_usec = usec; rttimer.it_interval.tv_sec = sec; rttimer.it_interval.tv_usec = usec; setitimer(ITIMER_REAL, &rttimer, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -