Reputation: 33
I have a linked list and I made a function to fetch a node. But I want to use it both to search by first or last name.
typedef struct people {
char name[60],
lastname[60];
struct people *next;
} people;
people *search(const char *key, people *list, FIELD) {
while (list && strcmp(key, list->FIELD) != 0) {
list = list->next;
}
return list;
}
Example:
people *aux;
aux = search("John", list_of_people, "name");
Or:
aux = search("Smith", list_of_people, "lastname");
There is a clear and efficient way to solve this problem without repeating code?
Upvotes: 3
Views: 994
Reputation: 40145
use offsetof(<stddef.h>)
macro.
E.g:
people *search(const char *key, people *list, size_t FIELD) {// FIELD is field offset,
while (list && strcmp(key, (char*)list + FIELD) != 0) {
list = list->next;
}
return list;
}
call
aux = search("John", list_of_people, offsetof(people, name));
aux = search("Smith", list_of_people, offsetof(people, lastname));
Upvotes: 2
Reputation: 206577
I would recommend using an enum
to do the different searches.
enum {SEARCH_BY_FIRSTNAME, SEARCH_BY_LASTNAME};
char* getSeachName(people* list, int searchBy)
{
return ( searchBy == SEARCH_BY_FIRSTNAME ? list->name : list->lastname );
}
people *search(const char *key, people *list, int searchBy) {
while (list && strcmp(key, getSearchName(list, searchBy)) != 0) {
list = list->next;
}
return list;
}
// Search by first name.
people *aux;
aux = search("John", list_of_people, SEARCH_BY_FIRSTNAME);
// Search by last name.
aux = search("Smith", list_of_people, SEARCH_BY_LASTNAME);
Upvotes: 2
Reputation: 25908
With just two fields, this seems like the obvious way:
people *search(const char *key, people *list, bool first) {
while (list && strcmp(key, first ? list->name : list->lastname) != 0) {
list = list->next;
}
return list;
}
For a more general case, something like this would work:
struct mystruct {
char field1[60];
char field2[60];
char field3[60];
char field4[60];
char field5[60];
struct mystruct * next;
}
char * get_field(struct mystruct * list, size_t field) {
char * fields[] = { list->field1, list->field2, list->field3,
list->field4, list->field5 };
return fields[field];
}
people *search(const char *key, people *list, bool first) {
while (list && strcmp(key, get_field(list, 3)) != 0) {
list = list->next;
}
return list;
}
Upvotes: 2