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:
74
src/main.c
74
src/main.c
@@ -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
50
test/Sorted 3.txt
Normal 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
10
test/Sorted 4.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Zachariah
|
||||
Arnold
|
||||
Barney
|
||||
George
|
||||
johnny
|
||||
Jordan
|
||||
Aaron
|
||||
abbie
|
||||
Jimmy
|
||||
Liz
|
||||
@@ -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")
|
||||
|
||||
40
test/Test.sh
40
test/Test.sh
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user