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?
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));
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;
}
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);
来源:https://stackoverflow.com/questions/23839743/pass-the-field-name-of-struct-to-access-inside-a-function