Sorting a last names that are contained within a structure
Author |
Message |
Rich Huebne #1 / 7
|
 Sorting a last names that are contained within a structure
I've created a nested structure, called a student that contains the following, among other things: typedef struct { char first[20]; char last[20]; Quote: } Name_t;
... similar for an Address_t; typedef struct { unsigned long studentid; Name_t name; Address_t address; Date_t DOB; Quote: } Student_t;
in my int main ( void ) function I have the following: Student_t student[100]; /* create an array of student structures */ Student_t *pStudent = student; /* create pointer to the array of students */ I've managed to allow the user to enter several students into this small array of students. Next, after entering as many as the user wishes, I want to sort them. I began with a simple bubble sort, but I got very stuck. the qsort function is giving me huge problems when I do something like this: qsort ( pStudent, 100, sizeof ( Student_t), compare ) My compare function basically uses the strcmp() on two last names within my student structure. I can list my students just fine, but just can seem to get my sorting right using pointers and no array notation. Any help is greatly appreciated. Thanks Rich Huebner ___________________________ Richard A. Huebner, M.S. RH Internet Marketing, LLC http://www.*-*-*.com/
|
Tue, 29 Mar 2005 08:33:12 GMT |
|
 |
Artie Gol #2 / 7
|
 Sorting a last names that are contained within a structure
Quote:
> I've created a nested structure, called a student that contains the > following, among other things: > typedef struct { > char first[20]; > char last[20]; > } Name_t; > ... similar for an Address_t; > typedef struct { > unsigned long studentid; > Name_t name; > Address_t address; > Date_t DOB; > } Student_t; > in my int main ( void ) function I have the following: > Student_t student[100]; /* create an array of student structures */ > Student_t *pStudent = student; /* create pointer to the array of > students */ > I've managed to allow the user to enter several students into this > small array of students. Next, after entering as many as the user > wishes, I want to sort them. I began with a simple bubble sort, but I > got very stuck. the qsort function is giving me huge problems when I > do something like this: > qsort ( pStudent, 100, sizeof ( Student_t), compare ) > My compare function basically uses the strcmp() on two last names > within my student structure.
Without seeing your compare function, there's little we can say...*show it*! Quote: > I can list my students just fine, but just can seem to get my sorting > right using pointers and no array notation. > Any help is greatly appreciated.
See above. HTH, --ag -- Artie Gold -- Austin, Texas
|
Tue, 29 Mar 2005 08:58:22 GMT |
|
 |
Ben Pfaf #3 / 7
|
 Sorting a last names that are contained within a structure
Quote:
> Student_t student[100]; /* create an array of student structures */ > Student_t *pStudent = student; /* create pointer to the array of > students */ > I've managed to allow the user to enter several students into this > small array of students. Next, after entering as many as the user > wishes, I want to sort them. I began with a simple bubble sort, but I > got very stuck. the qsort function is giving me huge problems when I > do something like this: > qsort ( pStudent, 100, sizeof ( Student_t), compare )
Are you sure that you want `pStudent' and not just `student' here? The former will always end up as a pointer to the first element in the array in this kind of syntax, but the latter might not if you've assigned something else to it. Are you sure that you want 100 there? If you only have 10 students so far, then it should be 10, not 100. `sizeof (Student_t)' is better written `sizeof *pStudent' (or `sizeof *student'. Show us the compare function. You probably got it wrong.
|
Tue, 29 Mar 2005 08:58:23 GMT |
|
 |
Rich Huebne #4 / 7
|
 Sorting a last names that are contained within a structure
Here's my compare function int compare ( Student_t s* ) { return strcmp ( s->name.last, (s + 1)->name.last); Quote: }
Part of what I want is to try to convert everything to pointers. I should be figuring out how many students have been entered, and only sort *that many* by placing that number in my qsort function? Thanks for the help, Rich
Quote:
>> Student_t student[100]; /* create an array of student structures */ >> Student_t *pStudent = student; /* create pointer to the array of >> students */ >> I've managed to allow the user to enter several students into this >> small array of students. Next, after entering as many as the user >> wishes, I want to sort them. I began with a simple bubble sort, but I >> got very stuck. the qsort function is giving me huge problems when I >> do something like this: >> qsort ( pStudent, 100, sizeof ( Student_t), compare ) >Are you sure that you want `pStudent' and not just `student' >here? The former will always end up as a pointer to the first >element in the array in this kind of syntax, but the latter might >not if you've assigned something else to it. >Are you sure that you want 100 there? If you only have 10 >students so far, then it should be 10, not 100. >`sizeof (Student_t)' is better written `sizeof *pStudent' (or >`sizeof *student'. >Show us the compare function. You probably got it wrong.
___________________________ Richard A. Huebner, M.S. RH Internet Marketing, LLC http://www.rhimc.com
|
Tue, 29 Mar 2005 09:08:31 GMT |
|
 |
Ben Pfaf #5 / 7
|
 Sorting a last names that are contained within a structure
Quote:
> Here's my compare function
Don't top-post. Quote: > int compare ( Student_t s* ) > { > return strcmp ( s->name.last, (s + 1)->name.last); > }
That cannot be your compare function. First of all, there's a syntax error: `Student_t s*' is not a valid declaration. That code won't compile. You probably mean `Student_t *s'. Don't retype code into your mail program. Cut and paste so that it comes out correctly (or, at least, the same). Second, your compiler should be giving you a diagnostic, because your comparison function does not have the proper prototype. A comparison function for use with qsort() must match the following prototype: int compare (const void *, const void *); Here is an example that works on a pair of pointers to integers: /* Comparison function for pointers to ints. */ int compare_ints (const void *pa, const void *pb) { const int *a = pa; const int *b = pb; if (*a < *b) return -1; else if (*a > *b) return +1; else return 0; Quote: } > Part of what I want is to try to convert everything to > pointers.
Why? What's wrong with array notation? By the way, do you realize that (s + 1)->name.last means exactly the same thing as s[1].name.last? The former is just a little less readable, that's all. Quote: > I should be figuring out how many students have been entered, > and only sort *that many* by placing that number in my qsort > function?
Yes. You're welcome. Quote:
> >> Student_t student[100]; /* create an array of student structures */ > >> Student_t *pStudent = student; /* create pointer to the array of > >> students */ > >> I've managed to allow the user to enter several students into this > >> small array of students. Next, after entering as many as the user > >> wishes, I want to sort them. I began with a simple bubble sort, but I > >> got very stuck. the qsort function is giving me huge problems when I > >> do something like this: > >> qsort ( pStudent, 100, sizeof ( Student_t), compare ) > >Are you sure that you want `pStudent' and not just `student' > >here? The former will always end up as a pointer to the first > >element in the array in this kind of syntax, but the latter might > >not if you've assigned something else to it. > >Are you sure that you want 100 there? If you only have 10 > >students so far, then it should be 10, not 100. > >`sizeof (Student_t)' is better written `sizeof *pStudent' (or > >`sizeof *student'. > >Show us the compare function. You probably got it wrong. > ___________________________
That's a nonstandard sig delimiter. The standard delimiter is "-- " on a line by itself. Fix it, please. Quote: > Richard A. Huebner, M.S. > RH Internet Marketing, LLC > http://www.rhimc.com
-- "The expression isn't unclear *at all* and only an expert could actually have doubts about it" --Dan Pop
|
Tue, 29 Mar 2005 09:32:09 GMT |
|
 |
Mike Wahle #6 / 7
|
 Sorting a last names that are contained within a structure
Quote: > I've created a nested structure, called a student that contains the > following, among other things: > typedef struct { > char first[20]; > char last[20]; > } Name_t; > ... similar for an Address_t; > typedef struct { > unsigned long studentid; > Name_t name; > Address_t address; > Date_t DOB; > } Student_t; > in my int main ( void ) function I have the following: > Student_t student[100]; /* create an array of student structures */ > Student_t *pStudent = student; /* create pointer to the array of > students */ > I've managed to allow the user to enter several students into this > small array of students. Next, after entering as many as the user > wishes, I want to sort them. I began with a simple bubble sort, but I > got very stuck. the qsort function is giving me huge problems when I > do something like this: > qsort ( pStudent, 100, sizeof ( Student_t), compare ) > My compare function basically uses the strcmp() on two last names > within my student structure. > I can list my students just fine, but just can seem to get my sorting > right using pointers and no array notation. > Any help is greatly appreciated. > Thanks > Rich Huebner
#include <stdio.h> #include <stdlib.h> #include <string.h> #define FNAME_LEN 21 #define LNAME_LEN 21 struct person { char firstname[FNAME_LEN]; char lastname [LNAME_LEN]; Quote: };
void show(const struct person *p, FILE *out) { fprintf(out, "%s %s\n", p->firstname, p->lastname); Quote: }
void showall(const struct person *p, FILE *out, size_t count, const char *prefix) { size_t i = count; fputs(prefix, out); while(i--) show(p++, out); fputc('\n', out); Quote: }
int byfirst(const void *left, const void *right) { return strcoll(((struct person *)left)->firstname, ((struct person *)right)->firstname); Quote: }
int bylast(const void *left, const void *right) { return strcoll(((struct person *)left)->lastname, ((struct person *)right)->lastname); Quote: }
int main() { struct person people[] = { {"John", "Doe"}, {"Jane", "Jones"}, {"Betty", "Williams"}, {"George", "Smith"} }; size_t elems = sizeof people / sizeof *people; showall(people, stdout, elems, "[Unsorted]\n"); qsort(people, elems, sizeof *people, byfirst); showall(people, stdout, elems, "[Sorted by first name]\n"); qsort(people, elems, sizeof *people, bylast); showall(people, stdout, elems, "[Sorted by last name]\n"); return 0; Quote: }
-Mike
|
Tue, 29 Mar 2005 10:13:58 GMT |
|
 |
Barry Schwar #7 / 7
|
 Sorting a last names that are contained within a structure
Quote:
>>> Student_t student[100]; /* create an array of student structures */ >>> Student_t *pStudent = student; /* create pointer to the array of >>> students */ >>> I've managed to allow the user to enter several students into this >>> small array of students. Next, after entering as many as the user >>> wishes, I want to sort them. I began with a simple bubble sort, but I >>> got very stuck. the qsort function is giving me huge problems when I >>> do something like this: >>> qsort ( pStudent, 100, sizeof ( Student_t), compare ) >>Are you sure that you want `pStudent' and not just `student' >>here? The former will always end up as a pointer to the first >>element in the array in this kind of syntax, but the latter might >>not if you've assigned something else to it. >>Are you sure that you want 100 there? If you only have 10 >>students so far, then it should be 10, not 100. >>`sizeof (Student_t)' is better written `sizeof *pStudent' (or >>`sizeof *student'. >>Show us the compare function. You probably got it wrong.
Please don't top post. I have reordered you response below. Quote: >Here's my compare function >int compare ( Student_t s* ) >{ > return strcmp ( s->name.last, (s + 1)->name.last); >}
This is the cause of one of your problems. The function does not match the prototype required by qsort. Why did you ignore the diagnostic your compiler produced? qsort does not compare adjacent elements of the array. It calls your function with two pointers to the elements it decides to compare. Your function must provide the results of that compare. Try something like int compare(const void *p1, const void *p2){ const Student_t *s1 = p1; const Student_t *s2 = p2; return strcmp(s1->name.last, s2->name.last);} Quote: >Part of what I want is to try to convert everything to pointers. I
Convert to pointers only those things for which it makes sense to do so. Quote: >should be figuring out how many students have been entered, and only >sort *that many* by placing that number in my qsort function?
Absolutely. What you have now will cause qsort to process uninitialized elements of the array which invokes undefined behavior. <<Remove the del for email>>
|
Tue, 29 Mar 2005 11:46:07 GMT |
|
|
|