/* * Copyright 2011 Steven Gribble * * This file is part of the UW CSE 333 course project sequence * (333proj). * * 333proj is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 333proj is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 333proj. If not, see . */ // Lecture 10 exercise 2 #include #include #include #include #include #include "sort.h" // This declares comparator function we pass in to // our sort routines. static int IntComparator(void *el1, void *el2); // This function reads a file into memory and returns // a pointer to the allocated memory buffer. static unsigned char *ReadFile(char *fname, int *retlen); // Converts the string to an int array, and returns a // pointer to the allocated int array. static int *StringToIntArray(unsigned char *filecontent, int *arrlen); #define BUBBLESORT 0 #define QUICKSORT 1 static void SortFile(char *fname, int whichsort); // Reads the file in, converts to int array, bubblesorts, frees // all of the resources. static void BubbleSortFile(char *fname) { SortFile(fname, BUBBLESORT); } // Reads the file in, converts to int array, quicksorts, frees // all of the resources. static void QuickSortFile(char *fname) { SortFile(fname, QUICKSORT); } int main(int argc, char **argv) { if (argc != 2) return EXIT_FAILURE; printf("Running quicksort on '%s'\n", argv[1]); QuickSortFile(argv[1]); printf("Running bubblesort on '%s'; this may take a while.\n", argv[1]); BubbleSortFile(argv[1]); printf("Done!\n"); return EXIT_SUCCESS; } static int IntComparator(void *el1, void *el2) { int *i1 = (int *) el1; int *i2 = (int *) el2; if (*i1 > *i2) return 1; if (*i1 == *i2) return 0; return -1; } #define READSIZE 1000 static unsigned char *ReadFile(char *fname, int *retlen) { unsigned char *buf = NULL; FILE *f; int readlen, count = 0; // Open up the file. f = fopen(fname, "rb"); if (f == NULL) return NULL; // Slurp in the file, READSIZE bytes at a time. buf = (unsigned char *) realloc(buf, READSIZE + 1); assert(buf != NULL); while ((readlen = fread(buf+count, 1, READSIZE, f)) > 0) { count += readlen; buf = (unsigned char *) realloc(buf, count + READSIZE + 1); assert(buf != NULL); } // Did we break because of an error? if (ferror(f)) { // Yes, so clean up and arrange to return NULL. free(buf); buf = NULL; count = 0; } // Clean up, null terminate, return. fclose(f); buf[count] = '\0'; *retlen = count; return buf; } static int *StringToIntArray(unsigned char *filecontent, int *arrlen) { int count = 0; int *retarray = NULL; char *nexttok = NULL; // Start by using strtok ("man strtok") to get the first newline- // separated token. nexttok = strtok((char *) filecontent, "\n"); // Then, loop through, converting the previously found token to // an integer, growing the array, and adding it. After this, // look for the next token. while(nexttok != NULL) { int nextint = 0; // Convert the line to an integer, growing the array to store it. retarray = (int *) realloc(retarray, sizeof(int) * (count + 1)); assert(retarray != NULL); assert(sscanf(nexttok, "%d", &nextint) == 1); retarray[count] = nextint; count++; // Look for the next token. nexttok = strtok(NULL, "\n"); } // Done! Return the array and count. *arrlen = count; return retarray; } static void SortFile(char *fname, int whichsort) { unsigned char *filecontent = NULL; int *intarray = NULL; int arrlen = 0, filelen = 0; // Read in the file. filecontent = ReadFile(fname, &filelen); if (filecontent == NULL) { fprintf(stderr, "Readfile returned empty content.\n"); exit(EXIT_FAILURE); } // Convert to an int array. intarray = StringToIntArray(filecontent, &arrlen); free(filecontent); if (intarray == NULL) { fprintf(stderr, "StringToIntArray returned empty array.\n"); exit(EXIT_FAILURE); } // Sort in place. if (whichsort == QUICKSORT) { QuickSort(intarray, arrlen, sizeof(int), &IntComparator); } else { BubbleSort(intarray, arrlen, sizeof(int), &IntComparator); } // Clean up. free(intarray); }