Sorting parallel arrays in C

  • 14 years ago
    I'm attempting to write code that will take in first names, last names and ages, then prints them alphabetically to the screen, with the correct first names, last names and ages.
    I'm just trying to sort the last name array first, but I can't see where I'm going wrong in this, when I run it I just get rubbishy output. When I debug it and step through it, it seems to be comparing the letters in the fname array.


    /*    Store lists of names (surname first) and ages in parallel arrays
       Sort the names into alphabetical order
       keeping the ages with the correct names. */

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #define CLASS_SIZE 3
    #define NAME_LEN 15

    int strncmp(const char *s1, const char *s2, size_t n);
    int main (void) {

       char lname[CLASS_SIZE][NAME_LEN];    /*Declare array of char*/
       char fname[CLASS_SIZE][NAME_LEN], temp;
       int age[CLASS_SIZE];
       
       
       for(int i=1; i<=CLASS_SIZE; i++){
       
           printf("Enter first name, last name and age please:\n");
           scanf("%s %s %d", fname, lname, &age);

       }

       for (int x=0; x<CLASS_SIZE; x++) {  /*Outer loop to go through each element of array*/

           for (int y=1; y<NAME_LEN; y++){  /* Loop through the elements of each name */

               if ((strncmp(lname[y-1], lname[y],NAME_LEN )>0)){
               temp = *lname[y];                /* Compare strings, swap if necessary */
               *lname[y] = *lname[y-1];
               *lname[y-1] = temp;
               }

           }

       }

       for(int a=1; a<=CLASS_SIZE; a++)
       
           printf("%s\n", lname[a] );  /* Print ordered names to screen */
       

       return 0;
    }


    Any help greatly appreciated! Thanks
  • 14 years ago

    First thing I spot it that this line is missing an asterisk:


    char fname[CLASSSIZE][NAMELEN], *temp;


    Then, you need to fix the loops appropriately (don't have time to test the correct solution here, you may get errors about l-values).


    Your scanf function call is also missing on the lname and fname, so you don't fill your arrays properly.


    Also, you ought not to need to declare "strncmp" before main. The inclusion of <string.h> means the function is already declared for you (unless you have been having specific issues).


    As an aside, is it the case that you have to use parallel arrays for some reason? You would save yourself a good deal of effort if you package the lastname, firstname and age into a struct:


    struct Person
    {
       char lname[NAMELEN];
       char fname[NAME
    LEN];
       int age;
    };


    This way, you store an array of pointers to the Person data type:


    typedef struct Person PersonData;


    PersonData* personList[CLASS_SIZE];


    and then you can sort on the last name, swap the pointers in the array in just the way you are doing, but the firstname, surname and age are all tied together, also allowing you to add extra properties to the person (e.g. weight) and that would automatically get sorted with no extra sorting effort required.


    Just a thought!


    Hope this is helpful.


  • 14 years ago

    Thanks for that. I made the changes you suggest, and got the following error messages:


    error C2106: '=' : left operand must be l-value
    error C2440: '=' : cannot convert from 'char *' to 'char [15]'



    So my complete code now looks like this:




    /*    Write a program that stores lists of names (surname first) and ages in parallel arrays
       and sorts the names into alphabetical order
       keeping the ages with the correct names. */


    include <stdio.h>


    include <string.h>


    include <ctype.h>


    define CLASS_SIZE 3


    define NAME_LEN 15



    int strncmp(const char *s1, const char *s2, size_t n);
    int main (void) {


       char lname[CLASSSIZE][NAMELEN];    /Declare array of char/
       char fname[CLASSSIZE][NAMELEN];
       int age[CLASSSIZE];
       char *temp;
       
       
       for(int i=1; i<=CLASS
    SIZE; i++){
       
           printf("Enter first name, last name and age please:\n");
           scanf("%s %s %d", fname, lname, &age);


       }


       for (int x=0; x<CLASS_SIZE; x++) {


           for (int y=1; y<NAME_LEN; y++){


               if (strncmp(lname[y-1], lname[y],NAME_LEN)>0){
                 temp = lname[y];
                 lname[y] = lname[y-1];
                 lname[y-1] = temp;
       
               }
           }
       }


       for(int a=1; a<=CLASS_SIZE; a++)
       
           printf("%s\n", lname[a] );
       


       return 0;
    }


    I need to use parallel arrays, I haven't covered structs yet.

  • 14 years ago

    Ok. I figured you might not have done structs yet... it would be the easiest way to do it so it made some sense!


    The l-value thing I also found when I quickly tried the code. Will try and post again over the weekend with a solution... the pointers are more complex because they are pointers to another pointer.

Post a reply

Enter your message below

Sign in or Join us (it's free).

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“There's no test like production” - Anon