0

I need to create a program that sorts command line strings. (Example output under code) This is the code I have so far:

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

int stringcomp (const void * x, const void * y);   

int main(int argc, char *argv[]){  
int i,j;
int k = 1;
char strings[argc-1][20]; 

strcpy(strings[0], argv[1]);
for(i=2; i< argc-1; i++){       
  strcat(strings[k],argv[i]);
  k++;
}
qsort(strings, argc, 20, stringcomp);
for(j=0 ; j < argc-1; j++){  
    printf("%s ", strings[j]);  
}  
return 0;  
}

int stringcomp (const void *x, const void *y) {  
return (*(char*)x -*(char*)y);  
}  

This is what I type into the command line: ./inOrder hello darkness my old friend

This is what I should get: darkness friend hello my old

But this is what I keep getting: ?darkness ?old ]@my

What am I doing wrong?

4
  • 1
    strings[k] is uninitialized and thus cannot use it in strcat. Commented Apr 24, 2016 at 23:05
  • @DavidC.Rankin we were required to use the qsort function Commented Apr 24, 2016 at 23:12
  • 1
    Why write your own stringcomp() function when the strcmp() library function already does what you want? Or if you do write your own stringcomp() (perhaps because, technically, strcmp() does not have the correct parameter types) then why are you not just using that to implement your own comparison? Commented Apr 24, 2016 at 23:17
  • Why use a 2D array of char for your temp array instead of a 1D array of char *? Not only would the latter help you avoid some initialization pitfalls, it would also remove the current 20-char limit on the strings you can sort. Commented Apr 24, 2016 at 23:20

2 Answers 2

3

Continuing from the comments, in order to compare the strings and sort an array of strings, you have 2-levels of indirection to deal with. So your stringcomp function will need to look something like:

int stringcomp (const void *x, const void *y) {  
    return strcmp (*(char * const *)x, *(char * const *)y);  
}

Beyond that, instead of copying strings, why not just sort an array of pointers to sort the arguments in correct order? Something like the following is all you need:

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

int stringcomp (const void * x, const void * y);   

int main (int argc, char **argv) {  

    char *strings[argc-1];  /* declare an array of pointers */
    int i;

    /* assign each argument to a pointer */
    for (i = 1; i < argc; i++)
        strings[i-1] = argv[i];

    /* sort the array of pointers alphabetically with qsort */
    qsort (strings, argc - 1, sizeof *strings, stringcomp);

    /* output the results */
    for (i = 0; i < argc-1; i++)
        printf("%s ", strings[i]);  

    putchar ('\n');

    return 0;  
}

int stringcomp (const void *x, const void *y) {  
    return strcmp (*(char * const *)x, *(char * const *)y);  
}

Example Use/Output

$ ./bin/sort_argv my dog has fleas
dog fleas has my

Look it over and let me know if you have additional questions.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much! Works perfectly!
Glad it helps -- there is always more than one way to skin-a-cat in C :)
0

I hope this helps. There is no need to use strcat. Also I removed some of your variables.

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

#define MAX_STRING 20 /* maximum string length */

int stringcomp (const void * x, const void * y);   

int main(int argc, char *argv[]){  

    int i;
    int argCount = argc-1;
    char strings[argCount][MAX_STRING]; 


    /* copy from argv */
    for (i = 0; i < argCount; i++){
        strcpy( strings[i], argv[i + 1]);
    }

    /* sort the words*/
    qsort (strings, argCount, MAX_STRING, stringcomp);

    /* print the results */
    printf("\n");
    for (i = 0; i < argCount; i++){
        printf("%s\n", strings[i]);
    }

    return 0;  
}


int stringcomp (const void *x, const void *y) {  
    return (*(char*)x -*(char*)y);  
}  

Hope this helps :)

Comments

Your Answer

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