notice it is just displaying only the first file. let's fix this issue.
we add while loop and used "argv[i]" instead of "argv[1]" . this way we can iteratively stdout files.
now it works fine.
#include <stdio.h>
#include <stdlib.h>
#define PAGELEN 20
#define LINELEN 512
void do_more(FILE *);
int get_input();
int main(int argc , char *argv[])
{
int i=0;
if (argc == 1){
printf("This is the help page\n");
exit (0);
}
FILE * fp;
while(++i < argc){
fp = fopen(argv[i] , "r");
if (fp == NULL){
perror("Can't open file");
exit (1);
}
do_more(fp);
fclose(fp);
}
return 0;
}
void do_more(FILE *fp)
{
int num_of_lines = 0;
int rv;
char buffer[LINELEN];
while (fgets(buffer, LINELEN, fp)){
fputs(buffer, stdout);
num_of_lines++;
if (num_of_lines == PAGELEN){
rv = get_input();
if (rv == 0)//user pressed q
break;//
else if (rv == 1)//user pressed space bar
num_of_lines -= PAGELEN;
else if (rv == 2)//user pressed return/enter
num_of_lines -= 1; //show one more line
else if (rv == 3) //invalid character
break;
}
}
}
int get_input()
{
int c;
c=getchar();
if(c == 'q')
return 0;
if ( c == ' ' )
return 1;
if ( c == '\n' )
return 2;
return 3;
return 0;
}
no change in main function , major change is in do_more function.
get_input compare input as ascii code and return integer.
when we input space and press enter will display next 20 lines.
when we input just enter only one more line will be display.
after Control Sequence Introducer ( \033[ ) we can use a specific Terminal Control Code like above.
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
//how to display text
printf("\e[7m This is in reverse video\n");
printf("\033[m This is in normal video\n");
printf("\033[1m This is bold \033[m \n");
printf("\033[4m This is underlined \033[m \n");
//Changing foreground and background colours
printf("\033[35m \033[40m This is in magenta colour with black back ground \033[39m \033[49m\n");
//cursor movement
printf("\033[10G This will start from column 10 \n");
printf("\033[10;20H This will appear in row 10 column 20 \n");
printf("\033[5B This is going to appear 5 lines below \n");
getchar();
//clearing parts of the screen
printf("\033[2J");
return 0;
}
works like css in browser , decoration is added.
#include <stdio.h>
#include <stdlib.h>
#define PAGELEN 20
#define LINELEN 512
void do_more(FILE *);
int get_input();
int main(int argc , char *argv[])
{
int i=0;
if (argc == 1){
printf("This is the help page\n");
exit (0);
}
FILE * fp;
while(++i < argc){
fp = fopen(argv[i] , "r");
if (fp == NULL){
perror("Can't open file");
exit (1);
}
do_more(fp);
fclose(fp);
}
return 0;
}
void do_more(FILE *fp)
{
int num_of_lines = 0;
int rv;
char buffer[LINELEN];
while (fgets(buffer, LINELEN, fp)){
fputs(buffer, stdout);
num_of_lines++;
if (num_of_lines == PAGELEN){
rv = get_input();
if (rv == 0){//user pressed q
printf("\033[1A \033[2K \033[1G");
break;
}
else if (rv == 1){//user pressed space bar
printf("\033[1A \033[2K \033[1G");
num_of_lines -= PAGELEN;
}
else if (rv == 2){//user pressed return/enter
printf("\033[1A \033[2K \033[1G");
num_of_lines -= 1; //show one more line
}
else if (rv == 3){ //invalid character
printf("\033[1A \033[2K \033[1G");
break;
}
}
}
}
int get_input()
{
int c;
printf("\033[7m --more--(%%) \033[m");
c=getchar();
if(c == 'q')
return 0;
if ( c == ' ' )
return 1;
if ( c == '\n' )
return 2;
return 3;
return 0;
}
using terminal code
- we go up one line
- erase current line
- move to column 1
if we compile this and run with some .txt files. there won't be any unintended enter space.
#include <stdio.h>
#include <stdlib.h>
#define PAGELEN 20
#define LINELEN 512
void do_more(FILE *);
int get_input(FILE*);
int main(int argc , char *argv[])
{
int i=0;
if (argc == 1){
do_more(stdin);
}
FILE * fp;
while(++i < argc){
fp = fopen(argv[i] , "r");
if (fp == NULL){
perror("Can't open file");
exit (1);
}
do_more(fp);
fclose(fp);
}
return 0;
}
void do_more(FILE *fp)
{
int num_of_lines = 0;
int rv;
char buffer[LINELEN];
FILE* fp_tty = fopen("/dev//tty", "r");
while (fgets(buffer, LINELEN, fp)){
fputs(buffer, stdout);
num_of_lines++;
if (num_of_lines == PAGELEN){
rv = get_input(fp_tty);
if (rv == 0){//user pressed q
printf("\033[1A \033[2K \033[1G");
break;//
}
else if (rv == 1){//user pressed space bar
printf("\033[1A \033[2K \033[1G");
num_of_lines -= PAGELEN;
}
else if (rv == 2){//user pressed return/enter
printf("\033[1A \033[2K \033[1G");
num_of_lines -= 1; //show one more line
}
else if (rv == 3){ //invalid character
printf("\033[1A \033[2K \033[1G");
break;
}
}
}
}
int get_input(FILE* cmdstream)
{
int c;
printf("\033[7m --more--(%%) \033[m");
c = getc(cmdstream);
if(c == 'q')
return 0;
if ( c == ' ' )
return 1;
if ( c == '\n' )
return 2;
return 3;
return 0;
}
if there are no command line argument. instead of just printing out "this is the help page" and exit. we take standard input as a parameter with do_more function.
first example = standard input is pointing to text file not keyborad so it will take armyfriends.txt as input.
second example = with redirection our executable file is taking the result of "cat" command as input
'Operating System > System Programming(Arif Butt)' 카테고리의 다른 글
Lec13) UNIX File Management (0) | 2021.06.29 |
---|---|
Lec12) UNIX File System Architecture (0) | 2021.06.27 |
Lec10) Heap Behind the Curtain (0) | 2021.06.23 |
Lec09) Stack Behind the Curtain (0) | 2021.06.22 |
Lec08) Exit Handlers and Resource Limits (0) | 2021.06.18 |