From 442a49ad5a48d417345959b903ae6a6d32d55759 Mon Sep 17 00:00:00 2001 From: Haidong Ji Date: Fri, 15 Apr 2022 15:51:30 -0500 Subject: Great C programming fun Excellent fundamentals and displine training, many tools and techniques exercises: gdb, emacs, valgrind, git --- 30_sort_lines/Makefile | 6 ++++ 30_sort_lines/README | 43 +++++++++++++++++++++++++++++ 30_sort_lines/grade.txt | 24 ++++++++++++++++ 30_sort_lines/sortLines.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 30_sort_lines/test.sh | 1 + 5 files changed, 144 insertions(+) create mode 100644 30_sort_lines/Makefile create mode 100644 30_sort_lines/README create mode 100644 30_sort_lines/grade.txt create mode 100644 30_sort_lines/sortLines.c create mode 100755 30_sort_lines/test.sh (limited to '30_sort_lines') diff --git a/30_sort_lines/Makefile b/30_sort_lines/Makefile new file mode 100644 index 0000000..28452a5 --- /dev/null +++ b/30_sort_lines/Makefile @@ -0,0 +1,6 @@ +CFLAGS=-ggdb3 -Wall -Werror -std=gnu99 -pedantic +sortLines: sortLines.c + gcc $(CFLAGS) -o sortLines sortLines.c + +clean: + rm -f sortLines *~ diff --git a/30_sort_lines/README b/30_sort_lines/README new file mode 100644 index 0000000..c5dcb2a --- /dev/null +++ b/30_sort_lines/README @@ -0,0 +1,43 @@ +For this problem, you will write a program (by modifying the provided +sortLines.c file) which sorts strings from input files. As we have not +yet covered sorting, we have provided the code that does the acutal +sorting. You can just call this function, which will sort the data. + + void sortData(char ** data, size_t count); + +The sortData function takes two arguments. The first is an array of strings. +The second is the length of that array. It will re-order the elements of the +array, such that they are sorted. + +Your task in this problem primarily centers around reading the data into +the array from the input file(s), so that it can be sorted. You will also +need to print the data after it is sorted, and free all of the memory you have allocated. + +Specifically, this program should take 0 or more command line arguments. + - If no arguments (other than its own name) are provided (argc ==1), then + your program should read from standard input, sort the lines of input, + print the results, free memory, and exit successfully. + - If 1 or more arguments are provided (argc > 1), then your program should + treat each argument as an input file name. It should open that file, + read all of the lines of data in it, sort the lines, print the results, + free the memory, and close the file. If any errors occur, your program + should print an appropriate error message and exit with EXIT_FAILURE. + If no errors occur, your program should indicate its success after processing + all of the files. + +Note that we now place *no* restriction on the length of any individual line of input. +You should therefore use the getline function to read an arbitrarily long line of +input, dynamically allocating space for it as needed. See the man page for getline +for more details. + +You should make sure your program valgrinds cleanly, including no memory leaks +before you submit it. As always, submit your code for grading. + +We've provided one simple test for you to use to test your program. Run it with: +./test.sh + +Hints: + - Don't forget to abstract code out into smaller function. In my solution, + I wrote 3 functions other than main (plus the 2 that are provided). + - Don't forget to draw pictures! They are even more important + as you use pointers more and more. diff --git a/30_sort_lines/grade.txt b/30_sort_lines/grade.txt new file mode 100644 index 0000000..19df8c9 --- /dev/null +++ b/30_sort_lines/grade.txt @@ -0,0 +1,24 @@ +Grading at Fri 17 Dec 2021 02:53:30 PM UTC +Attempting to compile sortLines.c +################################################# +testcase1: +testcase1 passed, your program successfully indicated a failure + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase2: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase3: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean +################################################# +testcase4: +Your output is correct + - Valgrind was clean (no errors, no memory leaks) +valgrind was clean + +Overall Grade: A diff --git a/30_sort_lines/sortLines.c b/30_sort_lines/sortLines.c new file mode 100644 index 0000000..3ef65ad --- /dev/null +++ b/30_sort_lines/sortLines.c @@ -0,0 +1,70 @@ +#include +#include +#include + + +//This function is used to figure out the ordering +//of the strings in qsort. You do not need +//to modify it. +int stringOrder(const void * vp1, const void * vp2) { + const char * const * p1 = vp1; + const char * const * p2 = vp2; + return strcmp(*p1, *p2); +} +//This function will sort and print data (whose length is count). +void sortData(char ** data, size_t count) { + qsort(data, count, sizeof(char *), stringOrder); +} + +void processFile(FILE * f) { + char ** lines = NULL; + char * curr = NULL; + size_t sz; + size_t i = 0; + + //processing: building string array + while (getline(&curr, &sz, f) >= 0) { + lines = realloc(lines, (i+1) * sizeof(*lines)); + lines[i] = curr; + curr = NULL; + i++; + } + + //sorting + free(curr); + sortData(lines, i); + + //printing then freeing each line + for (size_t j = 0; j < i; j++) { + printf("%s", lines[j]); + free(lines[j]); + } + + //clean up + free(lines); +} + +int main(int argc, char ** argv) { + + if (argc == 1) { + // stdin + processFile(stdin); + } + else { + for (int i = 1; i < argc; i++) { + // process each file one by one + FILE *f = fopen(argv[i], "r"); + if (f == NULL) { + fprintf(stderr, "Could not open file\n"); + return EXIT_FAILURE; + } + processFile(f); + if (fclose(f) != 0) { + fprintf(stderr, "Could not close file\n"); + return EXIT_FAILURE; + } + } + } + + return EXIT_SUCCESS; +} diff --git a/30_sort_lines/test.sh b/30_sort_lines/test.sh new file mode 100755 index 0000000..2d9b268 --- /dev/null +++ b/30_sort_lines/test.sh @@ -0,0 +1 @@ +printf "%s\n%s\n%s\n" "This is a sample test case" "it checks your program's one argument behavior" "go!" | tee | ./sortLines -- cgit v1.2.3