Thread: using qsort to sort an array of strings

  1. #1
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    122

    using qsort to sort an array of strings

    ARRRGGGHHH!!! ...I have looked everywhere, tried everything i can think of, but it just wont work!!!!

    I am writing a basic ls function, but am getting stuck at the qsort bit! ...I have an array full of directory / file names, but it is unsorted, basically, i need to use qsort, but i don't really know how to! Here is the code that creates the array and stuffs the directory and file names into it! ...It just needs sorting!!!!


    Code:
    void addDataToArray(int x, int y){
    
      char theArray[x][y];
      int z = 0;
    
      while ((dir = readdir(theDirectory)) != NULL){
        if (strncmp(dir->d_name, "." , 1) == 0){
          /* check to see if user is using option -a */
          if (aFlag == 1){
            strcpy(theArray[z], dir->d_name);
            z++;
          }
        }
        else{
          strcpy(theArray[z], dir->d_name);
          z++;
        }
      } /* loop */
      
      /* Sort the array contents into alphabetical order */
      /* qsort()'s parameters are:
      *    address of the first object
      *    number of objects
      *    sizeof(object)
      *    name of the compare-function */
      qsort(theArray,x,y,sortCompare);
    
      /* Print the directory contents */
      for (z = 0; z < x; z++)
        printf("%d: %s\n", z, theArray[z]);
    
    } /* addDataToArray */
    
    
    int sortCompare(char *str1, char *str2){
    
    return strcmp(str1,str2);
    
    }

    Thanks to anyone that helps!!!!!

  2. #2
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    122

    Done It!!!!

    Took a time-out break, thought about it, and came up with a maybe solution!!! ...well!!! ...It worked!!! ...for anyone that needs the code its:

    Code:
    void addDataToArray(int x, int y){
    
      char theArray[x][y];
      int z = 0;
    
      while ((dir = readdir(theDirectory)) != NULL){
        if (strncmp(dir->d_name, "." , 1) == 0){
          /* check to see if user is using option -a */
          if (aFlag == 1){
            strcpy(theArray[z], dir->d_name);
            z++;
          }
        }
        else{
          strcpy(theArray[z], dir->d_name);
          z++;
        }
      } /* loop */
      
      qsort((void*)theArray, (size_t)x, y, sortCompare);
    
      /* Print the directory contents */
      for (z = 0; z < x; z++)
        printf("%d: %s\n", z, theArray[z]);
    
    } /* addDataToArray */
    
    
    int sortCompare(const void *arg1, const void *arg2){
      
      return strcmp(arg1,arg2);
       
    }
    YIPPIEEE!!! ...Now can get on with the ls -l (file stat) switch!!!!!

  3. #3
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    you don't need sortCompare(), nor do you need the typcasting. The second parameter should be the number of valid entries in the array, not the maximum number of entries.
    Code:
    qsort(theArray, z, y, strcmp);
    I think file names can contain more than one period and can start with a period, so checking for "." and ".." will not work by checking the first character of the filename.

    Code:
    // check if d_name is a directory
    if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name,"..") != 0) ){
    The above is no guarentee that the file is not a directory. You also need to call stat() to get the file's attributes.

    Code:
       }
        else{
          strcpy(theArray[z], dir->d_name);
          z++;
        }
    what is the above supposed to do? As written, it has no affect unless readdir() fails, and in that case the above code is invalid because dir will not be a valid pointer. I think you have that code in the wrong spot.

    The last loop needs a different loop counter so that it can use z. Again, the loop should print only the first z number of valid strings.
    Code:
      for (i = 0; i < z;i++)
        printf("%d: %s\n", i, theArray[i]);
    Last edited by Ancient Dragon; 11-24-2005 at 05:49 PM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Also.

    > char theArray[x][y];
    Variable length arrays are not valid C (unless you're compiling in C99 mode).

    And neither your while loop, nor your strcpy() calls prevent overflow in either dimension of your array.


    Your function seems to be dependent on a morass of global variables.

  5. #5
    Matt Conway bobthebullet990's Avatar
    Join Date
    Nov 2005
    Location
    Cambridge
    Posts
    122
    Thanks for the help guys! ...So would you suggest rather than use a 2d array that is dynamic (because i know c doesn't support this!) i should use malloc?

    what are your thoughts???

    ...This code is a section of my ls command

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Sure, that'd be fine. You just have to make sure you free everything you allocate. Allocate N pointers to type, where N is the number of rows, and M type for each row.
    Code:
    char **twodee;
    size_t row, column, x;
    ...
    
    twodee = malloc( row * sizeof *twodee );
    for( x = 0; x < row; x++ )
        twodee[ x ] = malloc( column * sizeof **twodee );
    Free each row using a similar loop, and then free the pointers you allocated to hold each row when you're done. Hint: It looks exactly the same, just in reverse order of the two items.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    In fact, you would call malloc() within the loop once you know the length of the filename you want to store.

    Then all that remains is extending (using realloc - search the board for how to use it properly) to extend your array of pointers to encompass more strings.

    Of course then, your compare function would need to change since you're now sorting an array of char pointers, not an array of char arrays. On the plus side, the sorting will be much more efficient since swapping a pair of pointers is peanuts to swapping two arrays.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 07-05-2010, 10:43 AM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. How to sort an array of pointers to structure
    By broli86 in forum C Programming
    Replies: 3
    Last Post: 06-30-2008, 02:52 PM
  4. Sorting strings in an array
    By JLan in forum C Programming
    Replies: 4
    Last Post: 11-29-2003, 05:10 PM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM