1

I have been trying to make this program sort a 2d array of strings by column index.

I initialized this 2d array like this:

char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                         {"America", "Cycling", "Mens", "Gold"}, 
                         {"New Zealand", "Swimming", "Womens", "Silver"},   
                         {"India", "Badminton", "Mens", "Bronze"}};

And if I wanted to sort this array by the first column, the country names, then it would look something like this:

char *str[ROWS][COLS] = {{"America", "Cycling", "Mens", "Gold"}, 
                         {"India", "Badminton", "Mens", "Bronze"}};
                         {"New Zealand", "Swimming", "Womens", "Silver"},   
                         {"Russia", "Boxing", "Mens", "Gold"}};

This is what I have done so far, and it is nearly correct, except for the sorting method. I am having trouble implementing that.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROWS 4
#define COLS 4

void print_array(char *str[][COLS]);
void sort_array(char *str[][COLS], int nrows, int col);

int
main(void) {
    char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                             {"America", "Cycling", "Mens", "Gold"}, 
                             {"New Zealand", "Swimming", "Womens", "Silver"}, 
                             {"India", "Badminton", "Mens", "Bronze"}};
    int col;

    /* array before sorting */
    printf("Before: \n");
    print_array(str);

    /*choosing column index to sort by*/
    printf("\nChoose which column index you wish to sort by: ");
    if (scanf("%d", &col) != 1) {
        printf("Invalid input\n");
        exit(EXIT_FAILURE);
    }

    sort_array(str, ROWS, col);

    /* array after sorting */
    printf("\nAfter: \n");
    print_array(str);

return 0;
}

void
print_array(char *str[][COLS]) {
    int i, j;

    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%s  ", str[i][j]);
        }
        printf("\n");
    }
}

/*function used for sorting the array */
void
sort_array(char *str[][COLS], int nrows, int col) {
    int i, j;
    char *temp;

    for (i = 0; i < nrows; i++) {
        for (j = i; j < nrows; j++) {
            if(strcmp(str[i][col], str[j][col]) > 0) {
                temp = str[i][col];
                str[i][col] = str[j][col];
                str[j][col] = temp;
            }
        }
    }   
}

The issue I'm having is that my sorting algorithm is not swapping the rows, but the just strings in that column. I was also trying to use the insertion sort algorithm but I was not sure how to implement that with a 2d array of strings.

Any help would be appreciated :)

3 Answers 3

2

Since C11 you can do it as follows:

int compare_col(const void *a, const void *b, void *ctx) {
    int col = *(int*)ctx;
    return strcmp(((char**)a)[col], ((char**)b)[col]);
}

/*function used for sorting the array */
void sort_array(char *str[][COLS], int nrows, int col) {
    qsort_s(str, nrows, sizeof(char*)*COLS, compare_col, &col);
}
Sign up to request clarification or add additional context in comments.

2 Comments

I believe qsort_s is in Annex K only, so it is not necessarily supported even by all C11 conforming implementations… Which is kind of a pity, since the third argument to the comparator is a useful addition as you've shown.
Meanwhile, I would suggest using sizeof(*str) instead of sizeof(char*)*COLS in order to avoid redundancy, and possible errors if the type changes.
2

Using qsort, you need a comparator function taking as arguments pointers to two of the elements to be sorted. In this case the element to be sorted is an entire row in the 2D array. If you need to vary the sort column, you also need to make the variable holding it global (or else you need to create different comparators for each column).

static int sort_column = 0;

static int compare_rows(const void *a, const void *b) {
    return strcmp(((const char **)a)[sort_column], ((const char **)b)[sort_column]);
}

Then you simply call qsort with your array and the comparator function as arguments:

qsort(str, ROWS, sizeof(*str), (compare_rows));

Comments

1

Iterate through the rows. Compare the column for two rows, i and i + 1. As needed iterate through columns and swap the two rows. Repeat until there were no swaps.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROWS 4
#define COLS 4

void print_array(char *str[][COLS]);
void sort_array(char *str[][COLS], int nrows, int ncols, int col);

int
main(void) {
    char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                             {"America", "Cycling", "Mens", "Gold"},
                             {"New Zealand", "Swimming", "Womens", "Silver"},
                             {"India", "Badminton", "Mens", "Bronze"}};
    int col;
    int result = 0;
    int clean = 0;
    /* array before sorting */
    printf("Before: \n");
    print_array(str);

    /*choosing column index to sort by*/
    do {
        printf("\nChoose which column index you wish to sort by 0 to %d: ", COLS - 1);
        if ( ( result = scanf("%d", &col)) != 1) {
            printf("Invalid input\n");
            if ( result == EOF) {
                fprintf ( stderr, "problem getting input\n");
                exit(EXIT_FAILURE);
            }
            //clean input stream
            while ( ( clean = getchar ()) != '\n' && clean != EOF) {}
        }
    } while ( result != 1 || col < 0 || col >= COLS);

    sort_array(str, ROWS, COLS, col);

    /* array after sorting */
    printf("\nAfter: \n");
    print_array(str);
    return 0;
}

void
print_array(char *str[][COLS]) {
    int i, j;

    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%s  ", str[i][j]);
        }
        printf("\n");
    }
}

/*function used for sorting the array */
void
sort_array(char *str[][COLS], int nrows, int ncols, int col) {
    int i = 0, j = 0, swap = 0;
    char *temp;

    do {
        swap = 0;
        for ( i = 0; i < nrows - 1; i++) {//iterate through rows
            if ( strcmp( str[i][col], str[i + 1][col]) > 0) {//compare col for row i and i+1
                for ( j = 0; j < ncols; j++) {//iterate through cols and swap rows
                    temp = str[i][j];
                    str[i][j] = str[i + 1][j];
                    str[i + 1][j] = temp;
                }
                swap = 1;
            }
        }
    } while ( swap);//loop until no swaps
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.