Reading file data in a linked list in C

I am trying to create a simple phone book program that reads data from a file and saves the contents to specific nodes in a list. It works fine if I use the addEntry function with static data, for example:

addEntry("First", "Last", "555-555-5555");

If I try to read more than 1 record from a file, each record will look like the last record in the file. For example, if my file contains:

First1
Last1
123-456-7890
First2
Last2
987-654-3210

After saving the data in the list and printing, the result will look like this:

First2
Last2
987-654-3210

First2
Last2
987-654-3210

Instead of printing each specific name and number. This bothers me because this problem only occurs when I am reading data from a file, and not when I manually enter the name and number in the function call. Here are the definitions for main and addEntry, thanks 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;
    }
}
+3
3

node. , (, , ), .

, addEntry , .

, , , char .

, addEntry - :

tempNode = (struct bookNode *)malloc(sizeof(struct bookNode));
tempNode->firstName = (char *)malloc(strlen(fn)+1);
strcpy(tempNode->firstName, fn);

- . , , .

+2

bookNode . addEntry , , , : , , first, last num, main, .

addEntry , . , , , .

+1

.

, , :

char data[SIZE];
char *p;
/* get some useful value in data */
p = data;

, data , data (.. p = &data[0];). , p data. , data, data (data ). , , , .

, ? C . ( : , .)

, firstName, lastName phoneNumber , .

void addEntry(char *fn, char *ln, char *pn)
{
    struct bookNode *tempNode, *iterator;

    tempNode = malloc(sizeof *tempNode);
    tempNode->firstName = malloc(strlen(fn) + 1); /* +1 for terminating 0 */
    tempNode->lastName = malloc(strlen(ln) + 1);
    tempNode->phoneNumber = malloc(strlen(pn) + 1);

    /* Omitted check for malloc failures for brevity */
    strcpy(tempNode->firstName, fn);
    strcpy(tempNode->lastName, ln);
    strcpy(tempNode->phoneNumber, pn);

    /* Now continue with what you were doing */
}

freeEntry, .

- struct -:

#define MAX 20
struct bookNode
{
    char firstName[MAX];
    char lastName[MAX];
    char phoneNumber[MAX];
    struct bookNode *next;
} *head;

addEntry malloc() firstName, lastName phoneNumber, strcpy(). ( , . .) freeEntry() .

, . , , C strchr(). :

char *nl;
if ((nl = strchr(first, '\n')) != NULL) {
    *nl = '\0';
}

Finally, when you correct all of the above, you will find that in your phone book you get the last entry twice . In C, it feof()does not tell you if you are at the end of the file now: it tells you that the last attempt to read from the file failed because you were at the end of the file.

+1
source

Source: https://habr.com/ru/post/1728692/


All Articles