Question: I wrote this code in C for a doubly linked list that's supposed to contain the letters A-Z in each node then verify that the
I wrote this code in C for a doubly linked list that's supposed to contain the letters A-Z in each node then verify that the nodes do contain those letters in that order. How come am I getting a fail result when verifying the values both forwards and backwards? I ran my code through a C visualizer and can confirm that each node contains the letter that it's supposed to be holding. I can't seem to figure out why even though everything seems to be working perfectly.
HEADER FILE:
#ifndef LIST_H #define LIST_H #include// The type for a node in the list. struct node { struct node *next; struct node *prev; char *value; }; // The type for a list. typedef struct list { struct node head; } List; // The type for a list position. typedef struct list_pos { struct node *node; } ListPos; // Create and return an empty list. List *list_create(void); // Deallocate the list (and all of its values, if any). void list_destroy(List *lst); // Check if the list is empty. bool list_is_empty(const List *lst); // Get the position of the first element. ListPos list_first(List *lst); // Get the position after(!) the last element. ListPos list_end(List *lst); // Check equality between two positions. bool list_pos_equal(ListPos p1, ListPos p2); // Forward to the next position. ListPos list_next(ListPos pos); // Backward to the previous position. ListPos list_prev(ListPos pos); // Insert the value before the position and return the position of the new element. ListPos list_insert(ListPos pos, const char *value); // Remove the value at the position and return the position of the next element. ListPos list_remove(ListPos pos); // Get the value at the position. const char *list_inspect(ListPos pos); #endif /* LIST_H */
MAIN FILE:
#include
static bool verify_forwards(List *lst); static bool verify_backwards(List *lst);
static char* clone_string(const char* in) { size_t len = strlen(in); char* out = (char*)calloc(len + 1, sizeof(char)); strcpy(out, in); return out; }
static struct node* make_node(const char* value) { struct node *result = malloc(sizeof(struct node)); result->value = strdup(value); result->next = NULL; result->prev = NULL; return result; }
List* list_create(void) { List* lst = (List*)malloc(sizeof(struct list)); if (lst == NULL) { printf("No more memory! "); return 0; } lst->head.next = lst->head.prev = &lst->head; return lst;
}
// this function successively deletes each node for which space was allocated // in the heap if the list exists void list_destroy(List* lst) { if (lst != NULL) { free(lst); } }
// if there is no node except for the head in the linked list, or if the list is null, // then it highlights that the list is currently empty bool list_is_empty(const List* lst) { if (lst == NULL || (lst->head.next == lst->head.prev && lst->head.prev == &lst->head)) return true;
return false; }
ListPos list_first(List* lst) { ListPos pos = { .node = lst->head.next }; return pos; }
ListPos list_end(List* lst) { ListPos pos = { .node = &lst->head }; return pos; }
bool list_pos_equal(ListPos p1, ListPos p2) { int count = 0; if (p1.node == p2.node) { return count; } count++; p1.node = p1.node->next;
return -1; }
ListPos list_next(ListPos pos) { struct node* after = pos.node->next;
pos.node = after; return pos; }
ListPos list_prev(ListPos pos) { struct node* before = pos.node->prev;
pos.node = before; return pos; }
ListPos list_insert(ListPos pos, const char* value) { // Create a new node. struct node* node = make_node(value);
// Find nodes before and after (may be the same node: the head of the list). struct node* before = pos.node->prev; struct node* after = pos.node;
// Link to node after. node->next = after; after->prev = node;
// Link to node before. node->prev = before; before->next = node;
// Return the position of the new element. pos.node = node; return pos; }
ListPos list_remove(ListPos pos) { struct node* before = pos.node->prev; struct node* after = pos.node->next;
before->next = after; after->prev = before;
pos.node = after;
return pos; }
const char* list_inspect(ListPos pos) { return pos.node->value;
}
// Populate the list with A, B, ..., Z. static void add_values(List *lst) { char str[2] = "A"; ListPos pos = list_first(lst); for (char ch = 'A'; ch <= 'Z'; ch++) { str[0] = ch; pos = list_insert(pos, str); pos = list_next(pos); } }
// Traverse and verify a list in the forward direction. static bool verify_forwards(List *lst) { char str[2] = "A"; char ch = 'A' - 1; bool correct = true; ListPos pos = list_first(lst); ListPos end = list_end(lst); while (!list_pos_equal(pos, end)) { ch += 1; str[0] = ch; const char *str2 = list_inspect(pos); if (strcmp(str, str2) != 0) { correct = false; } pos = list_next(pos); } if (ch != 'Z') { correct = false; } return correct; }
// Traverse and verify a list in the backward direction. static bool verify_backwards(List *lst) { char str[2] = "Z"; char ch = 'Z' + 1; bool correct = true; ListPos pos = list_end(lst); ListPos first = list_first(lst); while (!list_pos_equal(pos, first)) { pos = list_prev(pos); ch -= 1; str[0] = ch; const char *str2 = list_inspect(pos); if (strcmp(str, str2) != 0) { correct = false; } } if (ch != 'A') { correct = false; } return correct; }
// Remove all the added values from the list. static void remove_values(List *lst) { ListPos pos = list_first(lst); for (char ch = 'A'; ch <= 'Z' && !list_is_empty(lst); ch++) { pos = list_remove(pos); } }
// Test program. int main(void) { // Create an empty list. List *lst = list_create();
// Add some values. add_values(lst);
// Verify the list forwards. bool forwards_ok = verify_forwards(lst); printf("Test traversal in forward direction ... %s ", forwards_ok ? "PASS" : "FAIL"); // I'm getting a fail result from both veryifying forwards and backwords for some reason. // despite running the code through a c visualizer and confirming that the list is filled // with the correct letters.
// Verify the list backwards. bool backwards_ok = verify_backwards(lst); printf("Test traversal in backward direction ... %s ", backwards_ok ? "PASS" : "FAIL");
// Remove all added values. remove_values(lst);
// Verify that the list is empty. bool empty_ok = list_is_empty(lst); printf("Test removal of all elements ... %s ", empty_ok ? "PASS" : "FAIL");
// Clean up allocated resources. list_destroy(lst);
return 0; }
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
