Added Descending Option and Command Line Parsing

I also added some appropriate tests. It appears to work, but tests 5 and 6 appear to fail due to a problem parsing the long --descending option.
This commit is contained in:
Aaron Helton
2019-10-30 23:46:04 -04:00
parent c0a621b71b
commit bdf409e42e
5 changed files with 180 additions and 6 deletions

View File

@@ -4,6 +4,13 @@
#include <name_string.h>
#include <string_vector.h>
#define ASCENDING 1
#define DESCENDING 0
// Nasty global variable needed here as there is no other way to pass state to the compare function.
// This variable should be kept static so no other unit may see it.
static int global_sort_order = ASCENDING;
/*
* Compare function to be used by qsort. Due to the implementation in the C
* Standard Library, this function necessarily accepts void * and must cast to
@@ -15,10 +22,16 @@ int compare(const void *str1, const void *str2)
const string *second = *(const string **) str2;
int res = compare_on_length(first, second);
if(res == 0)
if(0 == res)
{
return compare_on_alphabet(first, second);
}
// The user may have requested we sort in the other direction on length
if(global_sort_order == DESCENDING)
{
res = -res;
}
return res;
}
@@ -27,24 +40,73 @@ int compare(const void *str1, const void *str2)
* 1. Strings are sorted by length first, not alphabet.
* 2. Strings are sorted by alphabet only if they are the same length.
*/
void perform_length_alphabet_sort(string_vector *vector)
void perform_length_alphabet_sort(string_vector *vector, int ascending)
{
if(!ascending)
{
global_sort_order = DESCENDING;
}
qsort((void *) vector->array, vector->size, sizeof(string *), compare);
}
void print_usage()
{
fprintf(stderr, "Usage: name_sort [-d|--descending] <input_file>\n");
}
int main(int argc, char **argv)
{
if(argc < 2)
{
fprintf(stderr, "Usage: name_sort <input_file>\n");
print_usage();
return 1;
}
FILE *file = fopen(argv[1], "r");
int ascending = 1;
int double_dash_found = 0;
string *long_descending_option = create_from_cstr("descending");
//Parse our command line options
size_t option_index;
for(option_index = 1; option_index < argc && argv[option_index][0] == '-' && !double_dash_found; option_index++)
{
switch(argv[option_index][1]) {
case 'd': ascending = 0; break;
case '-':
if(argv[2] == '\0') {
//Double Dash with no other characters is traditional unix symbol of no more options, so we stop.
double_dash_found = 1;
} else {
string *option = create_from_cstr(argv[2]); //Pass in the remainder of the string
if(compare_on_alphabet(option, long_descending_option) == 0)
{
ascending = 1;
}
else
{
print_usage();
return 1;
}
}
break;
default:
print_usage();
return 1;
}
}
// At the end of our loop, option_index should be pointing to all non-option arguments. In this case it should
// only be one argument.
if(option_index != argc-1)
{
print_usage();
return 1;
}
char *input_file = argv[option_index];
FILE *file = fopen(input_file, "r");
string_vector *vector = create_vector(0);
read_file_into_vector(file, vector);
perform_length_alphabet_sort(vector);
perform_length_alphabet_sort(vector, ascending);
vector_print(vector);
destroy_vector(vector);
fclose(file);

50
test/Sorted 3.txt Normal file
View File

@@ -0,0 +1,50 @@
Fitzjerrell
Hendrickson
Clevenger
Bostwick
Cachedon
Giddings
Guenther
Hatfield
Kalivoda
Kirkland
Phillips
Reynolds
Sullivan
Williams
Byfield
Dulaney
Hagberg
Hillman
McCrave
Michael
Padgett
Routson
Starkey
Stegman
Adkins
Broome
Hickey
Laymon
Rogers
Tanton
Taylor
Baker
Ellis
Evans
Foley
Glock
Graff
Heigl
Lundy
McVey
Nylon
Peery
Reyes
White
Asby
Bain
Dean
Fife
Wile
Kha

10
test/Sorted 4.txt Normal file
View File

@@ -0,0 +1,10 @@
Zachariah
Arnold
Barney
George
johnny
Jordan
Aaron
abbie
Jimmy
Liz

View File

@@ -2,6 +2,8 @@ echo off
SET OUTPUT="output.txt"
SET OUTPUT2="output2.txt"
SET OUTPUT3="output3.txt"
SET OUTPUT4="output4.txt"
if exist %OUTPUT% del /f %OUTPUT%
NameSort.exe "Sort Me.txt" > %OUTPUT%
@@ -12,3 +14,13 @@ if exist %OUTPUT2% del /f %OUTPUT2%
NameSort.exe "Sort Me 2.txt" > %OUTPUT2%
fc %OUTPUT2% "Sorted 2.txt"
if %errorlevel% EQU 0 (echo "Success") else ( echo "Failure")
if exist %OUTPUT3% del /f %OUTPUT3%
NameSort.exe "Sort Me.txt" > %OUTPUT3%
fc %OUTPUT3% "Sorted 3.txt"
if %errorlevel% EQU 0 (echo "Success") else ( echo "Failure")
if exist %OUTPUT4% del /f %OUTPUT4%
NameSort.exe "Sort Me 2.txt" > %OUTPUT4%
fc %OUTPUT4% "Sorted 4.txt"
if %errorlevel% EQU 0 (echo "Success") else ( echo "Failure")

View File

@@ -2,12 +2,24 @@
OUTPUT="output.txt"
OUTPUT2="output2.txt"
OUTPUT3="output3.txt"
OUTPUT4="output4.txt"
OUTPUT5="output5.txt"
OUTPUT6="output6.txt"
rm -f $OUTPUT
rm -f $OUTPUT2
rm -f $OUTPUT3
rm -f $OUTPUT4
rm -f $OUTPUT5
rm -f $OUTPUT6
./NameSort "Sort Me.txt" > $OUTPUT
./NameSort "Sort Me 2.txt" > $OUTPUT2
./NameSort -d "Sort Me.txt" > $OUTPUT3
./NameSort -d "Sort Me 2.txt" > $OUTPUT4
./NameSort --descending "Sort Me.txt" > $OUTPUT5
./NameSort --descending "Sort Me 2.txt" > $OUTPUT6
diff "Sorted.txt" $OUTPUT
if [ $? -eq 0 ]; then
@@ -22,3 +34,31 @@ if [ $? -eq 0 ]; then
else
echo "Test 2 Failure"
fi
diff "Sorted 3.txt" $OUTPUT3
if [ $? -eq 0 ]; then
echo "Test 3 Success"
else
echo "Test 3 Failure"
fi
diff "Sorted 4.txt" $OUTPUT4
if [ $? -eq 0 ]; then
echo "Test 4 Success"
else
echo "Test 4 Failure"
fi
diff "Sorted 3.txt" $OUTPUT5
if [ $? -eq 0 ]; then
echo "Test 5 Success"
else
echo "Test 5 Failure"
fi
diff "Sorted 4.txt" $OUTPUT6
if [ $? -eq 0 ]; then
echo "Test 6 Success"
else
echo "Test 6 Failure"
fi