/* file: pbs-and.c G. Moody 25 February 2012 Read N sorted files, write lines common to all of them (logical "and") */ #include #include #include #define LMAX 128 char **line; FILE **ifile; int n; /* cleanup: close input files, free allocated memory, and quit. */ void cleanup() { while (n-- > 0) { fclose(ifile[n]); free(line[n]); } free(line); free(ifile); exit(0); } /* init: open input files and read the first line of each. If any input is unreadable or empty, the output will be empty, so exit immediately in this case. */ void init(int argc, char **argv) { if (argc < 3) exit(1); argc--; argv++; /* skip argv[0] */ ifile = (FILE **)calloc(argc, sizeof(FILE *)); line = (char **)calloc(argc, sizeof(char *)); for (n = 0; n < argc; n++) { if ((ifile[n] = fopen(argv[n], "r")) == NULL) cleanup(); line[n] = (char *)calloc(LMAX, sizeof(char)); if (fgets(line[n], LMAX, ifile[n]) == NULL) cleanup(); } } main(int argc, char **argv) { init(argc, argv); do { int i, j; for (i = 1; i < n; i++) { j = strcmp(line[0], line[i]); if (j < 0) { if (fgets(line[0], LMAX, ifile[0])) { i = 0; continue; } else cleanup(); } if (j > 0) { if (fgets(line[i], LMAX, ifile[i])) { i--; continue; } else cleanup(); } } fputs(line[0], stdout); } while (fgets(line[0], LMAX, ifile[0])); cleanup(); }