#include <stdio.h> #include <unistd.h> int main(int argc, char **argv) { int c, status = 0, n = 10; FILE *fp; extern void process(FILE *fp, int lines); while ((c = getopt(argc, argv, "n:")) != EOF) { if (c == 'n') { /* (for this exam question, calling atoi() was fine) */ char tmp; if (sscanf(optarg, "%d%c", &n, &tmp) != 1) status = 1; } else { status = 1; } } if (status) { fprintf(stderr, "usage: %s [-n num] [file ...]\n", argv[0]); return(1); } if (optind == argc) { process(stdin, n); } else { for (; optind < argc; optind++) { if ((fp = fopen(argv[optind], "r")) == NULL) { perror(argv[optind]); status = 1; } else { process(fp, n); fclose(fp); } } } return(status); }
Now for the process() function:
First, the way which is probably much more straightforward but has the serious
disadvantage that it pointlessly stores whole lines at a time, and breaks
extremely long lines thus miscounting:
void process(FILE *fp, int lines) { char buf[500]; for (; lines > 0 && fgets(buf, sizeof buf, fp); lines--) printf("%s", buf); }
Or, here is a better version which does not store whole lines and simply counts \n characters:
void process(FILE *fp, int lines) { int c; while (lines > 0 && (c = getc(fp)) != EOF) { putchar(c); if (c == '\n') lines--; } }