The only easy sorting methods rely on having the entire data set in memory. If that's possible, then your entire application could be streamlined by using an array (or linked list, but I think you'd use an array first.)
So, here's the test for whether you can expect your data to fit comfortably in memory.. You have 64 bytes of member record (right size, but wrong distribution. See below.) Multiply that by the number of members you expect this program to support. The result should be less that one fourth of your overall system memory. Looked at another way, divide your system memory by 4 times the record size (4*64 = 256) and that's the largest member database size you should ever consider. If you had 256MB (0.25 GB) of RAM, then you could handle up to a million gym members. If you have a million members, you can afford a computer with much more memory than that!
The data structure needs some more thought. The char join_date[10], for example. Is that supposed to be "mm/dd/yyyy"? If so, you need one more char for the '\0' string terminator. char join_date[11] as a minimum.
Is "int id[4]" really supposed to be an array of four ints? If it's four digits, then you just need a simple int. (...and 10,000 members will fit an any machine with memory measured in whole megabytes.)
There is a mixture of strings and ints. That's not good for effective memory use and it's even worse for portability. C aligns data in a processor-dependent fashion. I see 48 bytes of data, plus an array of 4 id numbers in your member record. You can be pretty successful if you put items intentionally on multiples of their largest divisor in (1,2,4,8). Having a 4-byte (presuming 32-bit ints) following a 10-byte name will waste 2 bytes on most compilers and fail to line to be portable on others. Put doubles first, ints and floats next, followed by short ints and chars. If a string has a multiple of 8 (total size including terminator) then you can move it up front. Try:
typedef struct
{
int id;
int age;
int weight;
int name[21];
char join_date[11];
char employment[21];
} member;
Then read in the data once from start to finish. At the beginning, you can use a fixed table size:
#define MAX_MEMBERS 4000 /* maximum number of members 8/
member mem_table[MAX_MEMBERS]; /* Table of members */
int num_members = 0; /* Current number of members in mem_table */
Then, open up your file, and read the whole table in with:
n = fread(mem_table, sizeof(member), MAX_MEMBERS, file_pointer);
if (0 != ferrror(file_pointer))
{
perror("file read error");
exit(1);
}
num_members = n;
That shows very simple error handling. A good idea, especially during debugging. Now, when you add a member: (1) check for num_members < MAX_MEMBERS; (2) add data into a your m_data struct, and (3) add to the table with mem_table[num_members++] = m_data.
FINALLY, the answer you your question. Use qsort(), from
. First, make a comparison function that compares names. It uses strcmp() from :
int compare_names(void *left, void *right)
{
member *lp = (member*)left, *rp = (member*)right;
return strcmp(lp->name, rp->name);
}
Then, sort the array with:
qsort(mem_table, num_members, sizeof(member), compare_names);
Sorting is the easy part.