RoadRunner RoadRunner - 3 months ago 8
C Question

String array Sorting C

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 :)

Answer

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
}

command line arguments

#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 tie);

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

    if ( argc != 3) {
        fprintf ( stderr, "syntax is\n%s column1 column2 < inputfile\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if ( ( result = sscanf ( argv[1], "%d", &col)) != 1 || col < 0 || col >= COLS) {
        fprintf ( stderr, "syntax is\n%s column1 column2 < inputfile\n", argv[0]);
        fprintf ( stderr, "column1 must be 0 to %d\n", COLS - 1);
        exit(EXIT_FAILURE);
    }

    if ( ( result = sscanf ( argv[2], "%d", &col2)) != 1 || col2 < 0 || col2 >= COLS) {
        fprintf ( stderr, "syntax is\n%s column1 column2 < inputfile\n", argv[0]);
        fprintf ( stderr, "column2 must be 0 to %d\n", COLS - 1);
        exit(EXIT_FAILURE);
    }

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

    sort_array(str, ROWS, COLS, col, col2);

    /* 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 tie) {
    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)
            || (( strcmp( str[i][col], str[i + 1][col]) == 0)
            && ( strcmp( str[i][tie], str[i + 1][tie]) > 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