aboutsummaryrefslogtreecommitdiff
path: root/ch7/7-08_print-file-pages.c
blob: 8f259b909c908cf539f08bd958d3d3e35a74a791 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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;
}