满足
1.回车 下一行
2.空格 下一页
3.q 退出
4.下方有”–More–(百分比)"
截图如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<sys/types.h>
#include<sys/ioctl.h>
#include<unistd.h>
#include<termios.h>
#define MOVEUP(x) printf("\033[%dA", (x))
#define MOVEDOWN(x) printf("\033[%dB", (x))
int PAGELINE;
int LENLINE;
int FILELINE = 0;
void do_more(FILE *fp);
void init(FILE *fp);
int main(int argc, char **argv) {
FILE *fp;
if (argc == 1) {
do_more(stdin);
}
else {
while (--argc) {
argv++;
if ((fp = fopen(*argv, "r")) != NULL) {
init(fp);
fclose(fp);
}
else {
exit(1);
}
if ((fp = fopen(*argv, "r")) != NULL) {
do_more(fp);
fclose(fp);
}
else {
exit(1);
}
}
}
return 0;
}
void init(FILE *fp) {
struct winsize size;
ioctl(STDIN_FILENO,TIOCGWINSZ,&size);
LENLINE = size.ws_col;
PAGELINE = size.ws_row - 2;
char line[LENLINE] = {0};
while (fgets(line, LENLINE, fp) != NULL) {
FILELINE++;
}
}
void do_more(FILE *fp) {
char line[LENLINE] = {0};
char more_str[] = "\033[7m --More-- \033[m";
int num_line = 0, reply, get_cmd(FILE *), cnt = 0;
FILE *fp_tty_in, *fp_tty_out;
fp_tty_in = fopen("/dev/tty", "r");
fp_tty_out = fopen("/dev/tty", "w");
struct termios initial_settings, new_settings;
tcgetattr(fileno(fp_tty_in), &initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ICANON;
new_settings.c_cc[VMIN] = 1;
if(tcsetattr(fileno(fp_tty_in), TCSANOW, &new_settings) != 0) {
fprintf(stderr, "could not set attributes\n");
}
while (fgets(line, LENLINE, fp) != NULL) {
if (num_line == PAGELINE) {
MOVEDOWN(2);
if (FILELINE == 0) FILELINE = 1;
printf("%s(%.2f%%)\n", more_str, (float)(cnt * 100.0 / FILELINE));
MOVEUP(1);
reply = get_cmd(fp_tty_in);
printf(" \n");
MOVEUP(1);
if (reply == 0) break;
num_line -= reply;
}
printf("%s", line);
/*
if( fputs(line, fp_tty_out) == EOF) {
tcsetattr(fileno(fp_tty_in), TCSANOW, &initial_settings);
exit(1);
}
*/
num_line++;
cnt++;
}
tcsetattr(fileno(fp_tty_in), TCSANOW, &initial_settings);
}
int get_cmd(FILE *cmd) {
int c, ret = -1;
while ((c = fgetc(cmd)) != EOF) {
if (c == 'q') ret = 0;
if (c == ' ') ret = PAGELINE;
if (c == '\n') ret = 1;
sleep(1);
return ret;
}
return ret;
}