Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This is quite a complex problem (at least for me) so bare with me while I explain it.

The initial problem is to read from a student database, search for the type of student (e.g. European, International, Funded etc.) and sort alphabetically by name.

To begin with I read from each individual file line by line using fgets() and parsed each line using sscanf() to store the students surname and first name in said variables.

Finally I used fprintf() to write each file to one single file which contains all the names of students in tabular format.

Easy enough so far.

Now comes the complicated part.

To save all the names from the combined file I used a 2D char array. It's 2D because I need to store each ROW number and #define BUFFER to specify how many chars in a line.

Now I need to pass the 2D array to a function to search for a student and sort the list. I have given it a try but I can only get it to display one name or random characters.

Below is snippets of my code so far...

What I have tried:

void parse_file_and_sort(void)
{
    FILE *fp = fopen("Combined.dat", "rb");
    // 2D array
    static char student[SIZE][BUFFER];

    unsigned short total;
    unsigned short i = 0;

    char input;
    char search_key[KEY_ID];

    if (fp != NULL)
    {
        while((fgets(student[i], BUFFER, fp)) != NULL)
        {
            // remove newline 
            if (student[i][strlen(student[i] - 1)] == '\n')
            {
                student[i][(strlen(student[i]) - 1)] = '\0';
                i++;
            }
        } // end while

        total = i;

        for(i = 0; i < total; i++)
        {
            // remove headings
            if (i == 0)
            {
                student[i][i] = '\0';
            }
        } // end for

        // close file stream
        fclose(fp);
        
        // passing array to function which will search for a keyword
        linear_search(student);
}

void linear_search(char student[][BUFFER])
{
    unsigned short i;

    for(i = 0; i < SIZE; i++)
    {
        printf("%-2u | %s\n", i, student[i]);
    }
}
Posted
Updated 21-Apr-17 8:32am

1 solution

Start off by not using a 2d array: create a Student struct and build a linked list (or an array only if there is a known maximum number of students) to hold them.
The Student struct has separate pointers for FirstName, LastName, Type.
Don't bother keeping a length of name, just null terminate each and lean it at that.

Each time you read a line, parse it into a new Student instance, and add the student to your collection. Create a function that takes a string (the line) and returns a pointer to a new Student.

Sorting is then just a matter of swapping the pointers to the Student Struct object about!

Searching is just a simple list lookup.

If you write a function that takes two Student pointers A & B and returns -1 for A greater than B, 0 for equal, and 1 for A less than B, you can use the same function for sorting and searching!

Make sense? Give it a try!
 
Share this answer
 
Comments
Konahrik16 21-Apr-17 14:46pm    
That makes sense and sounds straightforward to do! I'll try that out on the next program!

I've gone too far down the 2D array route on this one. Do you have any ideas as to why it displays random data or just the last name in the list?
OriginalGriff 21-Apr-17 15:31pm    
Seriously, throw it away!
The hardest thing in a developers life it to realise when enough is enough and something just plain wrong. The work invested in the idea is headed in the wrong direction, and it's going to make worse code - harder to get working, harder to maintain - so it's quicker, easier, and much better to throw it away and start again.
Trust me on this, I still have difficulty "letting go" from time to time!
Konahrik16 21-Apr-17 15:47pm    
Thanks for the advice ;)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900