User Guide User Guide: "more05" Text Viewer Welcome to "more05," a versatile text viewer for your terminal. This guide will help you get the most out of the program. Getting Started: To start using "more05," open your terminal and launch it with the following command: ./more05 <filename> Replace `<filename>` with the path to your text file. Displaying Line Numbers: With the `-n` option, you can display line numbers at the beginning of each line, providing clear references throughout your text. To enable this feature, simply include the `-n` flag in your command: ./more05 <filename> -n This will make it easy to identify specific lines in your text file. Searching Text: "more05" features a handy text search function: - While viewing the text, press `f`. - You'll be prompted to enter a search term. Type the text you're looking for and press "Enter." The program will find and highlight the text if it exists. In case the text isn't found, you'll receive an error message. Custom Page Length: If you'd like to control the number of lines displayed on each page, you can do so using the `-l` option followed by your desired page length (N lines): ./more05 <filename> -n -l N Replace `N` with your preferred page length. The default page length is set at 20 lines. Navigation: Navigating through the text is straightforward: - Press "Enter or space" to move to the next page. - To exit the program, press "q" Starting from a Specific Line: If you want to begin viewing the text from a specific line number, use the `-s` option. Specify the starting line with the `-s` option: ./more05 <filename> -n -s N Replace `N` with the line number from which you'd like to commence. Displaying Help: For quick reference to the program's options, you can use the `-h` flag to display the help message: ./more05 -h The source code : #include #include #include #include #include <stdio.h> <stdlib.h> <termios.h> <unistd.h> <string.h> #define DEFAULT_PAGE_SIZE 20 void set_terminal_raw_mode() { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term); } void reset_terminal_mode() { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag |= (ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term); } int search_and_display(FILE* file, const char* search_term, int show_line_numbers) { int current_line = 1; char line[1024]; int term_found = 0; while (fgets(line, sizeof(line), file) != NULL) { if (show_line_numbers) { printf("%6d ", current_line); } char* match = strstr(line, search_term); if (match != NULL) { // Print the line with the match highlighted char* start = line; while (start < match) { putchar(*start); start++; } printf("\x1B[7m%s\x1B[m", search_term); start += strlen(search_term); while (*start != '\0') { putchar(*start); start++; } term_found = 1; } else { // Print the entire line printf("%s", line); } current_line++; } return term_found ? current_line : -1; // Return -1 if search term not found } void display_more(FILE* file, int start_line, int page_size, const char* search_term, int show_line_numbers) { char c; int lines = 0; int current_line = start_line; int first_line_in_page = 1; fseek(file, 0, SEEK_SET); while ((c = getc(file)) != EOF) { if (show_line_numbers && first_line_in_page) { printf("%6d ", current_line); first_line_in_page = 0; } putchar(c); if (c == '\n') { lines++; current_line++; first_line_in_page = 1; if (lines == page_size) { lines = 0; printf("\x1B[7m-- More -- (Line %d) [q=quit, <SPACE>=next, <ENTER>=next, b=back, h=help, f=find, n=next, p=previous]\x1B[m", current_line); fflush(stdout); char input; do { input = getchar(); if (input == 'q') { return; } else if (input == 'h') { // ... (same as before) } else if (input == 'f') { printf("\nSearch: "); char search_buffer[256]; fgets(search_buffer, sizeof(search_buffer), stdin); search_buffer[strcspn(search_buffer, "\n")] = '\0'; search_term = search_buffer; int found_line = search_and_display(file, search_term, show_line_numbers); if (found_line != -1) { printf("\nSearch result: Found '%s' on line %d\n", search_term, found_line); } else { printf("\nSearch result: '%s' not found\n", search_term); } } } while (input != ' ' && input != '\n' && input != 'b'); printf("\r\x1B[K"); } } } } int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s <filename> [options]\n", argv[0]); return 1; } FILE* file = fopen(argv[1], "r"); if (file == NULL) { perror("Error opening file"); return 1; } int start_line = 1; int page_size = DEFAULT_PAGE_SIZE; const char* search_term = NULL; int show_line_numbers = 0; for (int i = 2; i < argc; i++) { if (strcmp(argv[i], "-h") == 0) { printf("\nOptions:\n"); printf(" q - Quit\n"); printf(" <SPACE> or <ENTER> - Next Page\n"); printf(" b - Previous Page\n"); printf(" h - Help\n"); printf(" f - Find (search for a word)\n"); printf(" n - Show line numbers (display line numbers at the beginning of each line)\n"); printf(" -l N - Set page length to N lines\n"); printf(" -s N - Start from line N\n"); return 0; } else if (strcmp(argv[i], "-f") == 0) { if (i + 1 < argc) { search_term = argv[i + 1]; i++; // Skip the next argument, which is the search term } else { fprintf(stderr, "Error: -f option requires a search term.\n"); return 1; } } else if (strcmp(argv[i], "-n") == 0) { show_line_numbers = 1; } else if (strcmp(argv[i], "-l") == 0) { if (i + 1 < argc) { page_size = atoi(argv[i + 1]); i++; // Skip the next argument, which is the page size if (page_size <= 0) { page_size = DEFAULT_PAGE_SIZE; } } else { fprintf(stderr, "Error: -l option requires a page size.\n"); return 1; } } else if (strcmp(argv[i], "-s") == 0) { if (i + 1 < argc) { start_line = atoi(argv[i + 1]); i++; // Skip the next argument, which is the starting line if (start_line <= 0) { start_line = 1; } } else { fprintf(stderr, "Error: -s option requires a starting line number.\n"); return 1; } } } set_terminal_raw_mode(); display_more(file, start_line, page_size, search_term, show_line_numbers); reset_terminal_mode(); fclose(file); return 0; } Alazhar Alabri -129050