Thread: Sorting Array

  1. #1
    Registered User
    Join Date
    Mar 2007
    Posts
    42

    Sorting Array

    Hello all,

    I am working on a project and I am having some difficulties sorting. I am trying to read in from a binary file and sort the structure but I am not sure I have it setup correctly. Any advice would be appreciated.

    Code:
    /* HorseData structure definition */
    struct horseData {
        int number;
        char name [ 25 ];
        int dob;
        int height;
        char father [ 25 ];
        char mother [ 25 ];
    
    }; /* End structure horseData */
    Code:
    /* Function Prototype */
    int newLine();
    void createData();
    int mainMenu();
    void addHorse();
    void addRace();
    void viewHorse();
    void sortData();
    void sortHorse();
    Code:
    /* Function sortHorse definition */
    void sortHorse()
    {
    
        int counter;
        int counter2;
        int hold;
        int pass;
        int record;
        int swap;
            
        /* Horses.dat file pointer */
        FILE *shPtr;
        
        /* Load horseData with default information */
        struct horseData sortHorse = { 0, "", 0, 0, "", "" };
            
        /* Fopen opens file; exits program if file cannot be opened */
        if ( ( shPtr = fopen( "horses.dat", "rb" ) ) == NULL ) {
            printf( "File could not be opened\n" );
        } /* End if */
            
        /* Read records from file */
        else {
            
            /* While not end of file */
            while( !feof( shPtr ) ) {
                    fscanf( shPtr, "%s", sortHorse.name );
                    printf( "%s", sortHorse.name );
                    record++;
            } /* End while */
                    
            /* Fclose closes the file */
            fclose( shPtr );
                    
            /* Begin sorting the array */ 
            for ( pass = 1; pass <= record; pass++ ) { 
                    
                    swap = 0; 
                        
                    /* Traverse and compare unsorted part of array */ 
                    for ( counter = 0; counter < record - 1; counter++ ) {              
                        
                        /* Compare adjacent array elements */ 
                        if ( sortHorse.name [ counter ] > sortHorse.name [ counter + 1 ] ){ 
                            swap = 1; 
                            hold = sortHorse.name [ counter ]; 
                            sortHorse.name [ counter ] = sortHorse.name [ counter + 1 ];; 
                            sortHorse.name [ counter + 1 ] = hold; 
                        } /* End if */
                    
                    } /* End for */ 
                        
                    /* Break loop if array is already sorted */ 
                    if ( !swap ) { 
                        break; 
                    } /* End if */
                    
            } /* End for */
            
        } /* End else */
            
        printf( "New sorted data - \n" );
            
        /* Fopen opens file; exits program if file cannot be opened */
        if ( ( shPtr = fopen( "sorted.txt", "w" ) ) == NULL ) {
            printf( "File could not be opened\n" );
        } /* End if */
        else {
            
            /* Output sort array */
            for( counter2 = 0; counter2 < record; counter2++ ) {
                    fprintf ( shPtr, "%s\n", sortHorse.name [ counter2 ] );
                    printf( " %s ", sortHorse.name [ counter2 ] );
            } /* End for */
                    
            /* Fclose closes the file */
            fclose( shPtr );
            
        } /* End else */
        
    } /* End sortHorse function */
    Thanks

    DMKanz07

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Why don't you trim it down to a basic shell of a program, then once you know how to sort an array, try it in your "real" program. Search the forums, there's loads of threads on sorting.


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

  3. #3
    Registered User
    Join Date
    Mar 2007
    Posts
    42
    I thought my post was broken down.

    Thanks

    DMKanz07

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Strings in C are not compared as you're trying to do it.

    THAT would be too easy!

    You'll need to add the header file "string.h", and use strcmp() to make the comparisons (which are done left to right, char by char, until a difference is found, or the end of the strings is reached).

    The return value of strncmp(), is your answer:

    This is how I think about this function:

    String1 - String2 > 0 means String1 is greater (same with if (strcmp(string1, string2) > 0).
    String1 - String2 < 0 means String 1 is less than String2 (same with if (strcmp(string1, string2) < 0).
    String1 - String2 == 0 means String1 is equal to String 2. Ditto for if (strcmp(string1, string2)== 0).

    As mentioned, there's a lot of other posts on this, as well.

    Adak
    Last edited by Adak; 04-23-2007 at 07:36 PM.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    No, this is broken down:
    Code:
    #include anyneededheaders.h
    void yoursort( int array[], size_t s )
    {
        ...your attempt here...
    }
    
    int main( void )
    {
        int array[10] = { 1, 17, 2, 77, 32, 88, 100, 23, 0, 11 };
        int x;
    
        for( x = 0; x < 10; x++ )
            printf( "array[ &#37;d ] is %d\n", x, array[ x ] );
        puts( "Sorting..." );
    
        yoursort( array, 10 );
    
        for( x = 0; x < 10; x++ )
            printf( "array[ %d ] is %d\n", x, array[ x ] );
    
        return 0;
    }
    Cut all the stuff you don't need out. Make a simple program. Test it. Once you've tested your function, try it in your real program.


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

  6. #6
    Registered User
    Join Date
    Mar 2007
    Posts
    42
    I am not even getting to the sort - it crash at the while piece of the code. Any ideas why

    Thanks

    DMKanz07

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You know you're allowed to scatter printf statements around to help you figure out what's going wrong, right? It's not going to do me any good to figure out your problem here, when you can figure it out on your own. Look at it this way: I fix it for you, you ask again, I fix it, you ask again. Or, I get you to figure out how to fix it on your own, and you now can debug your own problems in the future.


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

  8. #8
    Registered User
    Join Date
    Mar 2007
    Posts
    42
    Quzah

    I am not trying to be a pain but I dont understand how in the array I can sort the structure.

    My program has the user enter in a horse and it attributes

    i.e
    name, date of birth, height, father, mother

    this is written to a binary file. I am now trying to open the binary file and sort the data by name.

    I am not sure if your example is answering my question. Dont I need to sort by struct (i.e. sortHorse.name)

    Thanks

    DMKanz07

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Sure. Just pick whatever element of the structure you want to sort by, use it for comparison, and pass that over to your sort function. Look at qsort. You make a function to compare two elements and to return which one should go first. You pass it your data, the function used to sort them, and it does the rest.

    Now in your case, it sounds like you want the file sorted. This means you have to read the whole thing into memory, sort it, and write it back out again.

    Anyway, it's like I said, get a simple program working with sorting any old array, and once you know how to do that, it's easy to switch it from one array type to another. You just change what you're comparing.


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

  10. #10
    Registered User
    Join Date
    Mar 2007
    Posts
    42
    Okay - I am trying to select the element but when I try to scan in the elements I am not sure if the syntax is right
    Code:
    /* Load horseData with default information */
        struct horseData sortHorse = { 0, "", 0, 0, "", "" };
            
        /* Fopen opens file; exits program if file cannot be opened */
        if ( ( shPtr = fopen( "horses.dat", "rb" ) ) == NULL ) {
            printf( "File could not be opened\n" );
        } /* End if */
            
        /* Read records from file */
        else {
            
            /* While not end of file */
            while( !feof( shPtr ) ) {
                    fscanf( shPtr, "%s", sortHorse.name );
                    printf( "%s", sortHorse.name );
                    record++;
            } /* End while */                
            /* Fclose closes the file */
            fclose( shPtr );
    Thanks

    DMKanz07

  11. #11
    Registered User
    Join Date
    Mar 2007
    Posts
    42
    Here is my original sort program for a text file I created manually

    Code:
    #include <stdio.h>
    #include <string.h>
    
    /* Function main begins program execution */ 
    int main()
    {
        /* Declare variables */
        char name [ 10 ][ 30 ];
        int counter;
        int counter1;
        int counter2;
        char hold [ 30 ];
        int pass;
        int record;
        char sorted [ 30 ];
        int swap;
        char unsorted [ 30 ];
        
        /* Prompt user */
        printf( "Enter unsorted file name:  " );
            scanf( "%s", unsorted );
        printf( "Enter sorted file name:  " );
            scanf( "%s", sorted );
        
        /* cfPtr = unsorted_file.txt pointer */
        FILE *cfPtr;
        
        /* Fopen opens file; exits program if file cannot be opened */
        if ( ( cfPtr = fopen( unsorted, "r" ) ) == NULL ) {
            printf( "File could not be opened\n" );
        } /* End if */
        
        /* Read records from file */
        else {
            
            printf( "\n" );
            printf( "Original unsorted data - \n" );
            
            /* While not end of file */
            while( !feof( cfPtr ) ) {
                fscanf( cfPtr, "%s", name [ record ] );                  
                    printf( " %s ", name [ record ] );
                    record++;
            } /* End while */
            
            /* Fclose closes the file */
            fclose( cfPtr );
            
            printf( "\n\n" );
            
            /* Begin sorting the array */ 
            for ( pass = 1; pass <= record; pass++ ) { 
                    
                    swap = 0; 
    
                    /* Traverse and compare unsorted part of array */ 
                    for ( counter = 0; counter < record - 1; counter++ ) {              
                  
                         /* Compare adjacent array elements */ 
                         if ( strcmp ( name [ counter ], name [ counter + 1 ] ) > 0 ) { 
                            swap = 1; 
                            strcpy ( hold, name [ counter ] ); 
                            strcpy ( name [ counter ], name [ counter + 1 ] ); 
                            strcpy ( name [ counter + 1 ], hold ); 
                         } /* End if */
                     
                     } /* End for */ 
    
                     printf ( "After Pass %d: \n", pass );
    
                     /* Display array after each pass */ 
                     for ( counter1 = 0; counter1 <= record - 1; counter1++ ) { 
                          printf( " %s ", &name [ counter1 ] );
                     } /* End for */ 
    
                     printf( "\n\n" ); 
    
                     /* Break loop if array is already sorted */ 
                     if ( !swap ) { 
                          break; 
                     } /* End if */
                     
              } /* End for */
            
        } /* End else */
        
        printf( "New sorted data - \n" );
        
        /* Fopen opens file; exits program if file cannot be opened */
        if ( ( cfPtr = fopen( sorted, "w" ) ) == NULL ) {
            printf( "File could not be opened\n" );
        } /* End if */
        
        else {
        
                    /* Output sort array */
                    for( counter2 = 0; counter2 < record; counter2++ ) {
                         fprintf ( cfPtr, "%s\n", name [ counter2 ] );
                         printf( " %s ", name [ counter2 ] );
                    } /* End for */
                    
                    /* Fclose closes the file */
                    fclose( cfPtr );
        
        } /* End else */
            
        printf( "\n" );
        
        /* Indicates successful termination */
        return 0;
        
    } /* End Main */
    This program takes a text file that is unsorted and sorts it and saves it as a new file.

    What I am trying to do is take this same logic and apply using structures, but instead of sorting in alphabetic order I ask the user which attribute of the structure do you want to sort by alphabetically (i.e name, dob, height, father, mother, etc.)

    I am not sure of the syntax to use to sort by a structure

    Thanks

    DMKanz07

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    First I'd recommend spending some time in the FAQ to clear away common issues.
    FAQ > Explanations of... > Why it's bad to use feof() to control a loop
    FAQ > How do I... (Level 1) > Get a line of text from the user/keyboard (C)

    And your syntax indicates using either C99 or C++, I'm guessing C++. It would be better for in many respects a C programmer to learn C90.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    Registered User
    Join Date
    Mar 2007
    Posts
    42
    That was helpful Dave. Now I still do not understand how C opens a binary file, extracts a specific field and then sorts it but that field. Again I think understand how C is comparing the values and then swapping them (for a static file i.e text) but what is the syntax to open a binary file, select a specific field, place into an array, and then sort that array by this field.

    I have tried using both fread to read the file but I am not sure how to parse just the name and I have tried fscanf. Orignial post show both attempts.

    Thanks

    DMKanz07

  14. #14
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Reading a text file and reading a binary file completly different. You should open the file in the binary mode first. "rb" which opened the file in binary.

    To read a binary file you could use fread function which read the file byte by byte or a block of byte.

    using fread you coud read one whole record, by specifying the sizeof struct. This way you could read the whole file block by block where each block is a record.

    Once you have read the file, now u could get the each members of the block. Search up for reading a bianry file.

    ssharish2005

  15. #15
    Registered User
    Join Date
    Mar 2007
    Posts
    42
    Okay - thank you

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 03-31-2009, 12:34 PM
  2. two dimensional array sorting in C/C++
    By George2 in forum C Programming
    Replies: 16
    Last Post: 11-19-2006, 03:17 AM
  3. Type and nontype parameters w/overloading
    By Mr_LJ in forum C++ Programming
    Replies: 3
    Last Post: 01-02-2004, 01:01 AM
  4. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM
  5. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM