#include #include #include #include #include #include int usage(char *argv0) { printf("Usage: %s [-n number] [file ...]\n", argv0); return 2; } int main(int argc, char *argv[]) { char ch; int opt; FILE *file = stdin; int number = 10; int line = 0; bool multiple_files = false; while ((opt = getopt(argc, argv, "n:")) != -1) { switch (opt) { case 'n': if (optarg[0] == '-') { optarg++; } for (size_t i = 0; i < strlen(optarg); i++) { if (!isdigit(optarg[i])) { fprintf(stderr, "%s: invalid number of lines: '%s'\n", argv[0], optarg); return 1; } } number = atoi(optarg); break; case '?': fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], optopt); return usage(argv[0]); } } if (optind == argc) { // FIXME: this code is not clean goto READ_STDIN; } if (argc - optind > 1) { multiple_files = true; } for (; optind < argc; optind++) { if (strcmp(argv[optind], "-")) { file = fopen(argv[optind], "r"); if (file == NULL) { fprintf(stderr, "%s: ", argv[0]); perror(argv[optind]); return -1; } if (multiple_files) { printf("%s==> %s <==\n", (optind - 1 > argc - optind ? "\n" : ""), argv[optind]); } } else { file = stdin; if (multiple_files) { printf("%s==> %s <==\n", (optind - 1 > argc - optind ? "\n" : ""), "standard input"); } } READ_STDIN: line = 0; while ((ch = fgetc(file)) != EOF && line < number) { putchar(ch); if (ch == '\n') { line++; } } if (file != NULL && file != stdin) { fclose(file); } } return 0; }