/* commonLines - Print out lines in one file also found in another file using a minimum of * library routines. */ #include #include #include #define MAX_LINE_SIZE (4*1024) #define HASH_SIZE (64*1024-1) #define TRUE 1 #define FALSE 0 #define boolean int void usage() /* Explain usage and exit. */ { printf( "commonLines - Print out lines in file2 also found in file1 .\n" "usage:\n" " commonLines file1 file2\n" ); exit(-1); } /** Memory file helper routines **/ void *needMemory(size_t size) /* Return memory of given size or die trying. */ { void *pt = malloc(size); if (pt == NULL) { printf("Couldn't allocate %d bytes\n", (int)size); exit(-1); } return pt; } void *needClearMemory(size_t size) /* Return memory of given size cleared to zero or die trying. */ { void *pt = needMemory(size); memset(pt, 0, size); return pt; } /** File helper routines. **/ FILE *mustOpenToRead(char *fileName) /* Open a file to read or die trying. */ { FILE *f = fopen(fileName, "r"); if (f == NULL) { printf("Can't open %s\n", fileName); exit(-1); } return f; } boolean readLine(FILE *f, char line[MAX_LINE_SIZE]) /* Read a line from file. Return number of characters in line (0 at end of file) */ { int c, i; for (i=0; istring = cloneString(s); el->next = hash->table[slot]; hash->table[slot] = el; return el; } struct hashElement *hashFind(struct hash *hash, char *s) /* Return hash element if any associated with string. */ { struct hashElement *el; for (el = hash->table[hashFunction(s)]; el != NULL; el = el->next) { if (sameString(el->string, s)) return el; } return NULL; } struct hashElement *hashAddUnique(struct hash *hash, char *s) /* Add string to hash if it's not already there. Return hash element associated with string. */ { struct hashElement *el = hashFind(hash, s); if (el != NULL) return el; return hashAdd(hash, s); } /** Start of code that is specific to our task at hand. */ struct hash *hashLines(char *fileName) /* Read file and stuff all lines of it into a hash table that we return. */ { FILE *f = mustOpenToRead(fileName); struct hash *hash = hashNew(); char line[MAX_LINE_SIZE]; while (readLine(f, line)) hashAddUnique(hash, line); fclose(f); return hash; } void commonLines(char *file1, char *file2) /* commonLines - Print out lines in one file also found in another file using a minimum of * library routines.. */ { struct hash *hash = hashLines(file1); FILE *f = mustOpenToRead(file2); char line[MAX_LINE_SIZE]; while (readLine(f, line)) { if (hashFind(hash, line)) printf("%s\n", line); } fclose(f); } int main(int argc, char *argv[]) /* Process command line. */ { if (argc != 3) usage(); commonLines(argv[1], argv[2]); return 0; }