#include #include /* The C Programming Language: 2nd Edition * * Exercise 7-8: Write a program to print a set of files, starting each new one * on a new page, with a title and a running page count for each file. * * Notes: This could be done using functions written in exercise 7-2, but I * decided to go with library functions when I could. A caveat to keep in mind * on a real system is that the modern way to print some of the output is with * snprintf, which doesn't exist in ANSI C. There are places where, to be safe, * you should check bounds. Both line buffers are the same size here, however, * so I didn't bother since I know they can hold each others' contents. * * If you were to do this correctly, it would be a lot like the `less` program. */ /* The dimensions of a "page". Using a classic size because reasons. */ #define PAGE_WIDTH 80 #define PAGE_HEIGHT 24 int lineno = 0; int pageno = 0; FILE *fp; char buffer[PAGE_WIDTH]; char line[PAGE_WIDTH]; void page_break() { while (lineno < (PAGE_HEIGHT - 1)) { printf("\n"); lineno++; } } int endswith_nl(char *s) { int i; for (i = 0; s[i] != '\0'; i++) { } if (i > 0 && s[i - 1] == '\n') { return 1; } return 0; } void print_header(char *path) { pageno++; lineno++; char *prefix = "FILE:"; sprintf(line, "%-*s %-*s", (int) strlen(prefix), prefix, (PAGE_WIDTH - ((int)strlen(prefix))), path); printf("%s\n", line); } void print_footer(void) { page_break(); sprintf(line, "Page %d\n", pageno); printf("%*s", PAGE_WIDTH, line); lineno = 0; } int main(int argc, char *argv[]) { int i = 0; char c; while (argc > 1) { i++; argc--; if ((fp = fopen(argv[i], "r"))) { while ((c = fgetc(fp)) != EOF) { ungetc(c, fp); print_header(argv[i]); while (fgets(buffer, PAGE_WIDTH, fp)) { sprintf(line, "%s", buffer); printf("%s", line); if (!endswith_nl(line)) { printf("\n"); } lineno++; if (lineno == (PAGE_HEIGHT - 1)) { break; } } print_footer(); } fclose(fp); pageno = 0; } else { printf("err: could not open file '%s' for reading.\n", argv[i]); } } return 0; }