In C sorts an array of strings by string length

So I am injecting strings into an array mydata[10][81]

while ((ct<=10) && gets(mydata[ct]) != NULL && (mydata[ct++][0] != '\0'))

      

Then I use a for loop to create a second array of pointers

for (i=0;i<11;i++){
    ptstr[i] = mydata[i];
}

      

This is where I got stuck I know I need to use it somehow strlen

, but I can't even imagine how to get the length of a pointer and then re-assign that pointer to a new position based on the third optional length value

I hope this makes sense, I am so lost on how to do this or explain, I am just trying to sort the strings by length using array positions (not using something like qsort

)

I did a bit of work on this and came up with the following: any idea why it doesn't work?

void orderLength(char *ptstr[], int num){
int temp;
char *tempptr;
int lengthArray[10];
int length = num;
int step, i, j, u;
for (i=0; i<num;i++){
    lengthArray[i] = strlen(ptstr[i]);
}
for (step=0; step < length; step++){
    for(j = step+1; j < step; j++){
          if (lengthArray[j] < lengthArray[step]){
              temp = lengthArray[j];
              lengthArray[j] = lengthArray[step];
              lengthArray[step] =temp;
              tempptr=ptstr[j];
              ptstr[j]=ptstr[step];

              }
          }
    }
    for (u=0; u<num; u++){
        printf("%s \n", ptstr[u]);
        }    
} 

      

+3


source to share


3 answers


As pointed out in the comments by Deduplicator , use the ones qsort

defined in stdlib.h

.



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

#define ROWS 4
#define MAXLEN 20

int compare (const void * a, const void * b) {
    size_t fa = strlen((const char *)a);
    size_t fb = strlen((const char *)b);
    return (fa > fb) - (fa < fb);
}

int main(int argc, const char * argv[]) {
    char arr[ROWS][MAXLEN] = {
        "watfi",
        "wh",
        "barified",
        "foo"
    };
    qsort(arr, ROWS, MAXLEN, compare);
    return 0;
}

      

+5


source


In fact, a simple version might look like this. It's bubble sort , which is pretty slow for any reasonable size data, but it looks like you are only sorting 11 elements, so it doesn't matter here.

The key is an "if" statement that compares the lengths of two positions in the array. The next three lines change them if they don't work.

char* temp;
int length = 11;
int step, i;
for(step = 0; step < length - 1; step++)
    for(i = 0; i < length - step - 1; i++)
    {
        if(strlen(ptstr[i]) > strlen(ptstr[i+1]))
        {
            temp = ptstr[i];
            ptstr[i] = ptstr[i + 1];
            ptstr[i + 1] = temp;
        }
    }

      



Edit: If you want to sort by the content of the string and not by length, change the if statement to:

if(strcmp(ptstr[i], ptstr[i + 1]) > 0)

      

(note: you are better off using str n cmp where possible)

+1


source


To avoid calling multiple strlen () lines on the same lines, you can use an enumerated chain of structures, such as the following:

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

typedef struct  t_elem
{
    char        data[81];
    int         length;
    t_elem      *next;
};

int     main(int ac, char **av)
{   
    t_elem      *head;
    t_elem      *recent;
    t_elem      *current;

    while (/* string have to be sorted */)
    {
        if (head == NULL) {
            head = (t_elem *)malloc(sizeof(t_elem));
            head->data = //readTheFirstString();
            head->length = strlen(head->data);
            head->next = NULL;
        }
        else {
            recent = (t_elem *)malloc(sizeof(t_elem));
            recent->data = //readTheNextString();
            recent->length = strlen(recent->data);
            recent->next = NULL;

            if (recent->length < head->length) {
                recent->next = head;
                head = recent;
            }
            else {
                current = head;
                while (current->next && current->next->length < recent->length) {
                    current = current->next;
                }
                recent->next = current->next;
                current->next = recent;
            }
        }
    }

    // print the sorted chained list
    current = head;
    while (current->next) {
        printf("%s\n", current->data);
        current = current->next;
    }

    // free the list
    current = head;
    while (current->next) {
        recent = current;
        current = current->next;
        free(recent);
    }
    return (0);
}

      

+1


source







All Articles