I am trying to create a simple phonebook program that reads data from a file and stores the content into specific nodes in the list. It works fine if I use my addEntry function with static data, such as:
addEntry("First", "Last", "555-555-5555");
If I try to read more than 1 entry from the file, each entry just appears to be whatever the last entry was in the file. For example, if my file contained:
First1
Last1
123-456-7890
First2
Last2
987-654-3210
After storing the data in the list and printing, the output would look like:
First2
Last2
987-654-3210
First2
Last2
987-654-3210
Rather than printing each specific name and number. This confuses me because this issue only occurs when I read data from the file, not when I manually type in the name and number in a function call. Here are the definitions for main and addEntry, thank you in advance.
#include <stdlib.h>
#include <stdio.h>
struct bookNode
{
char * firstName;
char * lastName;
char * phoneNumber;
struct bookNode * next;
} * head;
FILE * fpointer;
void addEntry(char * fn, char * ln, char * pn);
void display();
int numEntries();
void writeBookData(struct bookNode * selection);
int main()
{
head = NULL;
addEntry("Test", "Name", "111-111-1111");
addEntry("Test2", "Name2", "222-222-2222"); // These entries will work as intended
int i;
fpointer = fopen("addressbook.dat", "a+");
if(fpointer == NULL)
{
printf("Error: addressbook.dat could not be opened.\n");
}
char first[20];
char last[20];
char num[20];
while (!feof(fpointer))
{
fgets(first, 20, fpointer);
fgets(last, 20, fpointer);
fgets(num, 20, fpointer);
//Removes newline characters from the ends of the names
i = 0;
while(first[i] != '\n')
{
i++;
}
first[i] = '\0';
i = 0;
while(last[i] != '\n')
{
i++;
}
last[i] = '\0';
// Adds the entry from the strings with the file data in them
addEntry(first, last, num);
}
fclose(fpointer);
display(); // typical linked list display function
int entryCount = numEntries();
printf("There are %d entries in this Address Book\n", entryCount);
return EXIT_SUCCESS;
}
void addEntry(char * fn, char * ln, char * pn)
{
struct bookNode * tempNode, * iterator;
tempNode = (struct bookNode *)malloc(sizeof(struct bookNode));
tempNode->firstName = fn;
tempNode->lastName = ln;
tempNode->phoneNumber = pn;
iterator = head;
// If the list is empty
if (head == NULL)
{
head = tempNode;
head->next = NULL;
}
// The list is not empty
else
{
while(iterator->next != NULL)
{
iterator = iterator->next;
}
tempNode->next = NULL;
iterator->next = tempNode;
}
}
You need to copy the string values to each new node. You are only storing the pointer to each string, but it is always the same pointers (first, last and num that are declared in main) so they all point to the same memory.
So in your addEntry method, you need to first allocate memory to store the string and then copy the string to the new memory.
Your example where you add the entries manually works because the char pointers point to static strings.
So in your addEntry method you should do something like this:
and then the same for last name and phone. Remember that you need to go through the list and free the memory for each string as well as for the nodes in the list as well.