#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--;
}
}