diff options
author | zlg <zlg@zlg.space> | 2017-02-20 03:21:59 -0800 |
---|---|---|
committer | zlg <zlg@zlg.space> | 2017-02-20 03:21:59 -0800 |
commit | 729b54b9f6921ca9a4ee91ddb743a6fb7203658c (patch) | |
tree | 02fa3224af2da0e107682c3bf626e8d00158fcf6 | |
parent | Solve Exercise 7-7: Match pattern in files (diff) | |
download | knr-729b54b9f6921ca9a4ee91ddb743a6fb7203658c.tar.gz knr-729b54b9f6921ca9a4ee91ddb743a6fb7203658c.tar.bz2 knr-729b54b9f6921ca9a4ee91ddb743a6fb7203658c.tar.xz knr-729b54b9f6921ca9a4ee91ddb743a6fb7203658c.zip |
Solve Exercise 7-8: Paged file print-outs
-rw-r--r-- | ch7/7-08_print-file-pages.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/ch7/7-08_print-file-pages.c b/ch7/7-08_print-file-pages.c new file mode 100644 index 0000000..8f259b9 --- /dev/null +++ b/ch7/7-08_print-file-pages.c @@ -0,0 +1,91 @@ +#include <stdio.h> +#include <string.h> + +/* 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; +} |