Brian
Brian

Reputation: 187

Reading text into linked list in C

I am trying to write a program that can read a text file into a linked list. However, while, the program does read in the stuff, when I print the list, the values are off.

  1. The first character of the name is always removed.

  2. The integer and float values are incorrect when list is displayed.

I have been working on this for a very long time and cannot figure out the problem. Any help is appreciated.

This is the file I am reading from:

#1 Flat Blade Screwdriver
12489
36
.65
1.75
#2 Flat Blade Screwdriver
12488
24
.70
1.85
#1 Phillips Screwdriver
12456
27
0.67
1.80
#2 Phillips Screwdriver
12455
17
0.81
2.00
Claw Hammer
03448
14
3.27
4.89
Tack Hammer
03442
9
3.55
5.27
Cross Cut Saw
07224
6
6.97
8.25
Rip Saw
07228
5
6.48
7.99
6" Adjustable Wrench
06526
11
3.21
4.50

This is my code:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

typedef struct inventory
{
    char invName[36];
    int  invPartNo;
    int  invQOH;
    float invUnitCost;
    float invPrice;
}stock;

struct  NODE
{
    union
    {
        int  nodeCounter;
        void  *dataitem;
    }item;
    struct NODE *link;
};

struct NODE *InitList();
void DisplayNode(struct inventory *);
struct inventory * ReadData(FILE *);
void DisplayList(struct NODE *);
struct NODE* GetNode(FILE *);
void  Add2List(struct NODE *, struct NODE *);
struct NODE* SearchList(struct NODE *, int );
void  DeleteNode(struct NODE *, int );


int main(int argc, char* argv[])
{
    struct NODE *header;
    header = InitList();

    int i, j;
    i = 0;
    FILE *fp = fopen("input.txt", "r");

    //remove \n char from end of lines


    if( fp != NULL )
    {
        while(!feof(fp))
        {
            struct NODE *nNode =  (struct NODE*)malloc(sizeof NODE);
            struct inventory *newNode =  (struct inventory*)malloc(sizeof inventory);

            fgets(newNode->invName, 100, fp);
            fscanf(fp, " %d %d %f %f ", &newNode->invPartNo,&newNode->invQOH,&newNode->invUnitCost,&newNode->invPrice);
            //fscanf(fp,"%s %d %d %f %f ", newNode->invName, &newNode->invPartNo,&newNode->invQOH,&newNode->invUnitCost,&newNode->invPrice);
            nNode->item.dataitem = newNode;
            nNode->item.nodeCounter++;
            Add2List(header, nNode);
        }
     }
    DisplayList(header);

    return 0;
}

struct NODE *InitList()
{
    struct NODE *temp = (struct NODE*)malloc(sizeof NODE);

    temp->item.nodeCounter = 0;
    temp->link = NULL;
    return temp;
}


void  Add2List(struct NODE *start, struct NODE *NewNode)
{
    struct NODE *current = start;

    while (current->link != NULL)
        current = current->link;

    current->link = NewNode;
    NewNode->link = NULL;

    start->item.nodeCounter++;
}


struct NODE* GetNode(FILE *fptr)
{
    struct NODE *temp = (struct NODE*)malloc(sizeof NODE);

    temp->item.dataitem = ReadData(fptr);
    temp->link = NULL;

    return temp;
}


void DisplayList(struct NODE *start)
{
    struct NODE *current = start->link;

    while (current != NULL)
    {
        DisplayNode((struct inventory *)current->item.dataitem);
        current = current->link;

    }
}


void DisplayNode(struct inventory *stuff)
{
    printf("Name: %s\n", stuff->invName);
    printf("Part Number: %d\n", stuff->invPartNo);
    printf("Quantity on hand: %d\n", stuff->invQOH);
    printf("Unit Cost: %0.2f\n", stuff->invUnitCost);
    printf("Price %0.2f\n\n", stuff->invPrice);
}


struct inventory * ReadData(FILE *fptr)
{
    struct inventory *temp = (struct inventory *)malloc(sizeof inventory);

    if(fptr==stdin)
        printf("Enter item name: ");
    fscanf_s(fptr, "%s", temp->invName);
    if(fptr==stdin)
        printf("Enter item part number: ");
    fscanf_s(fptr, "%d", &temp->invPartNo);
    if(fptr==stdin)
        printf("Enter item quantity on hand: ");
    fscanf_s(fptr, "%d", &temp->invQOH);
    if(fptr==stdin)
        printf("Enter item unit cost: ");
    fscanf_s(fptr, "%f", &temp->invUnitCost);
    if(fptr==stdin)
        printf("Enter item price: ");
    fscanf_s(fptr, "%f", &temp->invPrice);

    return temp;
}

struct NODE* SearchList(struct NODE *start, int oldData)
{
    struct NODE* current = start;
    struct inventory * st = (struct inventory *)current->link->item.dataitem;

    while (st->invPartNo != oldData && current != NULL)
    {
        current = current->link;
        if(current->link)
            st = (struct inventory *)current->link->item.dataitem;
    }
    return current;
}

void  DeleteNode(struct NODE *start, int oldData)
{
    struct NODE *current, *oldNode;

    current = SearchList( start, oldData);
    oldNode = current->link;
    current->link = oldNode->link;
    free(oldNode);
    start->item.nodeCounter -= 1;
}

void readFile()
{
    stock array[20]; //9 items to read from list
    int i, j;
    i = 0;
    FILE *fp = fopen("input.txt", "r");
    if( fp != NULL )
    {
        while(fgets(array[i].invName, sizeof array[i].invName, fp))
        {
            fscanf(fp,"%d %d %f %f ",&array[i].invPartNo,&array[i].invQOH,&array[i].invUnitCost,&array[i].invPrice);
            i++;
        }
     }

}

Upvotes: 2

Views: 732

Answers (1)

Dabo
Dabo

Reputation: 2373

This

        nNode->item.dataitem = newNode;
        nNode->item.nodeCounter++;
        Add2List(header, nNode);

has no chance to work, and i guess this is the main issue. Your item is union

union
{
    int  nodeCounter;
    void  *dataitem;
}item; 

and union is a special data type available in C that enables you to store different data types in the same memory location. which means after you assign address of newNode to nNode->item.dataitem here

        nNode->item.dataitem = newNode;

you corrupt the address in here

        nNode->item.nodeCounter++; 

I guess in your case item should be a struct

Upvotes: 2

Related Questions