From e098bc87ac1a53472dd46e23627fd1edd5ab90d0 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Tue, 5 Nov 2019 15:03:46 +0100 Subject: [PATCH] Added exercise 26 (sort cars) --- cars/sort_cars.c | 92 ++++++++++++++++++++++++++++++ cars/test_sort_cars.sh | 126 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 cars/sort_cars.c create mode 100755 cars/test_sort_cars.sh diff --git a/cars/sort_cars.c b/cars/sort_cars.c new file mode 100644 index 0000000..46f5181 --- /dev/null +++ b/cars/sort_cars.c @@ -0,0 +1,92 @@ +#include +#include +#include + +struct car { + char maker[21]; + char model[21]; + unsigned int power; + unsigned int price; +}; + +enum sort { + MODEL, + MAKER, + PRICE, + POWER +}; + +enum sort sorting = MAKER; +int asc = 0; + +int asc_desc(int o) { + if (asc) { + return o; + } else { + return o * -1; + } +} + +int compare_cars(const void* car1, const void* car2) { + const struct car* c1 = car1; + const struct car* c2 = car2; + // printf("%s %s %u %u\n", c1->maker, c1->model, c1->power, c1->price); + // printf("%s %s %u %u\n", c2->maker, c2->model, c2->power, c2->price); + + switch (sorting) { + case MODEL: + return asc_desc(strcmp(c1->model, c2->model)); + case MAKER: + return asc_desc(strcmp(c1->maker, c2->maker)); + case PRICE: + return asc_desc(c1->price - c2->price); + case POWER: + return asc_desc(c1->power - c2->power); + } +} + +int main(int argc, const char** argv) { + if (argc == 2) { + if (!strcmp(argv[1], "+model")) { sorting = MODEL; asc = 1; } + else if (!strcmp(argv[1], "-model")) { sorting = MODEL; asc = 0; } + else if (!strcmp(argv[1], "+maker")) { sorting = MAKER; asc = 1; } + else if (!strcmp(argv[1], "-maker")) { sorting = MAKER; asc = 0; } + else if (!strcmp(argv[1], "+price")) { sorting = PRICE; asc = 1; } + else if (!strcmp(argv[1], "-price")) { sorting = PRICE; asc = 0; } + else if (!strcmp(argv[1], "+power")) { sorting = POWER; asc = 1; } + else if (!strcmp(argv[1], "-power")) { sorting = POWER; asc = 0; } + else { fprintf(stderr, "wrong argument\n"); return 3; } + } else if (argc > 2) { + fprintf(stderr, "wrong arguments\n"); + return 3; + } + + size_t length = 1024, i = 0; + struct car* A = malloc(sizeof(struct car) * length); + if (!A) { + perror("Cannot allocate cars"); + return 1; + } + while(!feof(stdin)) { + scanf("%s %s %u %u\n", A[i].maker, A[i].model, &A[i].power, &A[i].price); + i++; + if (i == length) { + length *= 2; + struct car* B = realloc(A, sizeof(struct car) * length); + if (!B) { + perror("Cannot expand cars"); + free(A); + return 2; + } + A = B; + } + } + + qsort(A, i, sizeof(struct car), compare_cars); + + for (size_t j = 0; j < i; j++) { + printf("%s %s %u %u\n", A[j].maker, A[j].model, A[j].power, A[j].price); + } + + free(A); +} diff --git a/cars/test_sort_cars.sh b/cars/test_sort_cars.sh new file mode 100755 index 0000000..b971b17 --- /dev/null +++ b/cars/test_sort_cars.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +# +# test 1 +# +cat > test1.in < test1.out +cat > test1.expected < test1.out +cat > test1.expected < test1.out +cat > test1.expected < test1.out +cat > test1.expected < test1.out +cat > test1.expected < test1.out +cat > test1.expected < test1.in +./sort_cars +price < test1.in > test1.out +sort -n -k 4 < test1.in > test1.expected +if diff -q test1.out test1.expected; then + rm -f test1.out test1.expected +else + echo "Test 7 FAILED" + diff test1.out test1.expected + exit 1 +fi +rm -f test1.in +echo PASSED