Such code is being rewritten over and over The list must be reimplemented for each and every data item struct int_item { int value; struct int_item *next; }; while (fgets(line, 16, stdin)) { item = malloc(sizeof(*item)); item->value = atoi(line); list_insert(head, item); } struct str_item { char str[16]; struct str_item *next; }; while (fgets(line, 16, stdin)) { item = malloc(sizeof(*item)); memcpy(item->str, line, 16); list_insert(head, item); } And double-linked lists are not so easy to write and rewrite Simple lists allow some operations, but are quite limited You really need something more to do stuff different from reversing