Hello everyone,
I have created a program that counts, prints, adds and deletes nodes in a linked list. I am having a problem with the delete function of the program. The struct contains a name value (ex. Paul).
When I call the fuction del_node, I am using strcmp to see if the value returned is 0, if it is, the function should mark the current pointer as "del_node" and free the space allocated for that node at the end of the function call, relinking the pointers as needed.
It seems that strcmp in the del_node function isn't comparing my two pointers correctly. Below is the code:
Code:
#include <stdio.h>
#include <string.h>
#define DEBUG
typedef struct linked_list LIST;
int print_menu(void);
void print_nodes(LIST *head, int *reval);
int count_nodes(LIST *head);
LIST *add_node(LIST *head, int *reval);
LIST *del_node(LIST *head);
struct linked_list {
struct linked_list *next;
char name[30];
};
enum reval {SUCCESS, FAIL};
int main(void)
{
char line[100];
int i, count = 0;
int option;
int reval = SUCCESS;
LIST *first_node = NULL;
LIST *node_2 = NULL;
LIST *head = NULL; // Points to first node in the list
first_node = malloc(sizeof(LIST));
if (first_node == NULL) {
printf("Out of memory.\n");
return 1;
}
node_2 = malloc(sizeof(LIST));
if (node_2 == NULL) {
printf("Out of memory.\n");
return 1;
}
strcpy(first_node->name, "Paul");
strcpy(node_2->name, "Susan");
head = first_node;
first_node->next = node_2;
node_2->next = NULL;
while (1) {
option = print_menu();
switch (option) {
case 1:
count = count_nodes(head);
printf("\nNumber of nodes in list: %d\n", count);
break;
case 2:
print_nodes(head, &reval);
break;
case 3:
head = add_node(head, &reval);
break;
case 4:
head = del_node(head);
break;
default:
printf("Incorrect menu option.\n");
break;
}
printf("\nWould you like to continue? (Y)es or (N)o? ");
fgets(line, sizeof(line), stdin);
printf("\n");
if ((line[0] == 'y') || (line[0] == 'Y'))
continue;
else
break;
}
if (count != 0) {
free(first_node);
free(node_2);
}
return reval;
}
// print_menu() definition
int print_menu(void)
{
char line[100];
int option;
printf("Linked Lists\n");
printf("------------\n");
printf("1. Count number of links\n");
printf("2. Print names in list\n");
printf("3. Add a name to the list\n");
printf("4. Delete a name from the list.\n\n");
printf("What would you like to do: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &option);
return option;
}
// node_count() definition
void print_nodes(LIST *head, int *reval)
{
LIST *current;
if (head == NULL) {
printf("\nThere are no names in the list.");
*reval = FAIL;
}
current = head;
printf("\n");
while (current != NULL) {
printf("Name: %s\n", current->name);
current = current->next;
}
}
int count_nodes(LIST *head)
{
LIST *current;
int count = 0;
current = head;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}
// add_node() definition
LIST *add_node(LIST *head, int *reval)
{
LIST *current = NULL, *before = NULL, *after = NULL, *new_node = NULL;
char line[100];
int count = 0;
int value;
new_node = malloc(sizeof(LIST));
if (new_node == NULL) {
printf("Out of memory.\n");
*reval = FAIL;
}
current = head;
printf("Enter a name: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%s", new_node->name);
while (1) {
value = strcmp(new_node->name, current->name);
if (current == NULL)
break;
if ((value < 0) && (count == 0)) {
new_node->next = current;
head = new_node;
break;
}
else if ((value < 0) && (count != 0)) {
new_node->next = current;
before->next = new_node;
break;
}
else if (value > 0) {
if (current->next == NULL) {
new_node->next = NULL;
current->next = new_node;
break;
}
before = current;
current = current->next;
count++;
}
else if (value == 0)
break;
}
return head;
}
// del_node() definition
LIST *del_node(LIST *head)
{
LIST *current = NULL, *del_node = NULL, *before = NULL, *after = NULL;
char name[100];
int count = 0;
int value;
current = head;
printf("Enter a name to remove from the list: ");
fgets(name, sizeof(name), stdin);
#ifdef DEBUG
int i;
printf("\n");
for (i=0; i<strlen(name); i++)
printf("name[%d]: %c\n", i, name[i]);
printf("string length of name is: %d\n", strlen(name));
printf("string length of current->name is: %d\n\n", strlen(current->name));
printf("current->name[0] is: %c\n", current->name[0]);
printf("current->name[1] is: %c\n", current->name[1]);
printf("current->name[2] is: %c\n", current->name[2]);
printf("current->name[3] is: %c\n", current->name[3]);
printf("current->name[4] is: %c\n", current->name[4]);
printf("\nBegin for loop\n");
for (i=0; i<strlen(current->name); i++);
printf("current->name[%d]: %c\n", i, current->name[i]);
#endif
value = strcmp(name, current->name);
printf("value is: %d\n", value);
while (current != NULL) {
if (value == 0) {
if (count == 0) { // check to see if first_node contains the name
head = current->next;
del_node = current;
break;
}
del_node = current;
after = current->next;
before->next = after;
break;
}
else {
count++;
before = current;
current = current->next;
}
}
if (del_node == NULL)
printf("\nName not found.\n");
free(del_node);
return head;
}
The output of the debug section is:
Code:
Enter a name to remove from the list: Paul
name[0]: P
name[1]: a
name[2]: u
name[3]: l
name[4]:
string length of name is: 5
string length of current->name is: 4
current->name[0] is: P
current->name[1] is: a
current->name[2] is: u
current->name[3] is: l
current->name[4] is:
Begin for loop
current->name[4]:
value is: 10
Name not found.
From what I can see, the value returned from strlen(current->name) isn't the same as strlen(name). Does this have to do with the fact that current->name is on the heap and name is in the stack?
If I print each element from current->name array individually, it prints successfully, but when I try to use the "for" loop, it only prints the last character (current->name[4]). I'm pretty sure this is the reason strcmp is failing....
Any help would be appreciated. Thank you.