简体   繁体   中英

Sort a 2D array of strings in C

I'm currently reading in a list of words from a file and trying to sort them line by line. I can read each line in and print the words out just fine, but I can't seem to sort each line individually. The first line is sorted, but the second is not. Can anyone see where I'm going wrong? Thanks!

    int fd;
    int n_char = 0;
    int charCount = 0, wordCount = 0, lineCount = 0;
    int wordsPerLine[100];

    char buffer;
    char words[6][9];

    fd = open(inputfile, O_RDONLY);
    if (fd == -1) {
        exit(1);
    }

    wordsPerLine[0] = 0;

    /* use the read system call to obtain 10 characters from fd */
    while( (n_char = read(fd, &buffer, sizeof(char))) != 0) {

        if (buffer == '\n' || buffer == ' ') {
            words[wordCount][charCount] = '\0';
            charCount = 0;
            wordCount++;
            wordsPerLine[lineCount] += 1;
            if (buffer == '\n') {
                lineCount++;
                wordsPerLine[lineCount] = 0;
            }
        } else {
            words[wordCount][charCount++] = buffer;
        }
    }

    printf("Num Words: %d  ---  Num Lines: %d\n", wordCount, lineCount);

    char tmp[9];

    int m, n;
    int i, x, totalCount = 0;
    for (i = 0; i < lineCount; i++) {
        for (x = 0; x < wordsPerLine[i]; x++) {

            /* iterate through each word 'm' in line 'i' */
            for(m = 0; m < wordsPerLine[i]; m++) {
                for(n = 0; n < wordsPerLine[i]; n++) {
                    if(strcmp(words[n-1], words[n])>0) {
                        strcpy(tmp, words[n-1]);
                        strcpy(words[n-1], words[n]);
                        strcpy(words[n], tmp);
                    }
                }
            } /* end sorting */

        }
    }

    printf("Sorted:\n");
    totalCount = 0;
    for(i = 0; i < lineCount; i++) {
        printf("Line %d (%d words)\n", i + 1, wordsPerLine[i]);
        for(x = 0; x < wordsPerLine[i]; x++) {
            printf("%s\n", words[totalCount++]);
        }
    }

My sample input file is:

great day out
foo bar food

Let's go by small parts...

To see if the problem is in the reading, comment the reading part and try to add:

 char words[][9] = {"great", "day", "out", "foo", "bar", "food"};

and set the counters to the value they would with this input also...

Your loop is accessing some data out of the bounds... I would recommend you to try your sorting code with an array of numbers first and see if it is sorting them correctly...

#include<stdio.h>
#define N 6
int main()
{
   char words[][9] = {"great", "day", "out", "foo", "bar", "food"};
   int numbers[] = {20, 10, 50, 5, 30, -50};
   int i, j, temp;

   for(i = 0; i < N - 1; i++)
      for(j = 0; j < N - 1; j++)
          if(numbers[j] > numbers[j + 1])
          {
             temp = numbers[j];
             numbers[j] = numbers[j + 1];
             numbers[j + 1] = temp;
          }


    for(i = 0; i < N; i++)
    {
        printf("%d\n", numbers[i]);
        //printf("%s\n", words[i]);
    }
}

Note also that this is the least efficient implementation of bubble sort (but is the same you provided), you can improve it by adding a variable to check in the inner loop some change happened for instance(which would mean that it is already sorted and you can stop sorting)...

Also, after each iteration on the outter loop one element is going to be placed in its final place (try to find out which one), which means that you won't need to consider this element in the next iteration, so after each iteration in the outer loop the number of elements compared in the inner loop can be reduced by 1...

you can find more info about bubble sort here

/* iterate through each line */
for (i = 0; i < lineCount; i++) { 

    /* iterate through each word 'm' in line 'i' */
    for(m = 0; m < wordsPerLine[i]; m++) {
        for(n = m+1; n < wordsPerLine[i]; n++) {
            if(strcmp(words[n + totalCount], words[m + totalCount]) < 0) {
                strcpy(tmp, words[m + totalCount]);
                strcpy(words[m + totalCount], words[n + totalCount]);
                strcpy(words[n + totalCount], tmp);
            }
        }
    } /* end sorting */  
    totalCount += wordsPerLine[i];
}

I just needed to keep a running count of each word per line, so i know what line to start comparing with

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM