Home > other >  How Can Read Values from File, store them in a structure and find their average, sum, product etc...
How Can Read Values from File, store them in a structure and find their average, sum, product etc...

Time:01-17

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>

#define SIZE 1024

typedef struct rational
{
    int  numerator;
    int denominator;
    struct rational *next;
}rational;

double add_rationals(rational*);
void multiply_rationals();
void subtract_rationals();
void divide_rationals();
void read_data(FILE*, int[], int*);
void display_values(rational*);
rational * createList(int []);

int main()
{
    system("cls");


    FILE* ifp;
    ifp = fopen("file.txt", "r");
    int data[SIZE] ={0};
    int sz = SIZE;
    
    read_data(ifp, data, &sz);
    
    printf("\nRead Integer Count:%d\n", sz);

    rational* HEAD = createList(data);
    display_values(HEAD);
 
    /*
        want to start after the 1st number because 1st number is size of arr
        data[0] is the 1st number we just read from the text
    */

    //display_values(HEAD, data[0]); // passing data[0] as size cuz the 1st number is size


}



// double add_rationals(rational* r)
// {
//     rational* c;
//     c = r;

//     static double x = 0 , y = 0, sum;
//     x = r->numerator;
//     y = r->denominator;

//     while(c->next != NULL)
//     {
//         sum = x/y   add_rationals(r->next);
//     }

//     return sum;
    
// }

rational * createList(int data[])
{
    rational *head = NULL;
    rational *temp = NULL;
    rational *p = NULL;
    rational *r = NULL;
    int count = 0;
    
    for (int i = 1; i < 5; i  )
    {
        temp = (rational*)malloc(sizeof(double));
        temp->numerator = data[i];
        temp->denominator = data[  i];
        
        temp->next = NULL;

        if(head == NULL) // Checking if the List has started yet
        {
            count  ;
            head = temp;
            printf("\nHEAD NUMERATOR: %d, HEAD DENOMINATOR: %d\n\n", head->numerator, head->denominator);
        }
        else
        {
            p = head;
            while (p->next != NULL)
            {
                count  ;
                p = p->next;

            }
            p->next = temp;
            
        }
        
    }
}




void display_values(rational* HEAD)
{
    rational* o = NULL;
    o = HEAD;
    while(o->next != NULL)
    {
        printf("\n\nNUM: %d, DEN: %d", o->numerator, o->denominator);
        o = o->next;
    }
    
}

void read_data(FILE* fptr, int d[], int*size)
{
    *size = 0;
    while ((fscanf(fptr, "%d", &d[*size])) == 1)
        (*size)  ;
    
}

PROBLEMS>>>

  1. I am unable to display all the elements from the linked list in the function void display_values() function
  2. The pre-requisites are like this .. take the 1st number from a text file and create an array of that size... Let me show you with example: 2 5 2 6 7 being the integers in the text file

I want to read the 2nd and 4th items to a struct as numerators and the 3rd and 5th as denominators I want 5/2 and 6/7 as rationals and do all these operations with them Like Add, Sub, Mul , Div...etc

CodePudding user response:

You are making it much too complex.

You should:

  1. read a single integer from the input file
  2. allocate an array of that number of rational struct
  3. loop that number of times reading one struct and making it point to the next in the array
  4. make next=NULL for the last element of the array

That way, you use one single malloc, and avoid the data integer array.

Possible code:

...
rational* read_data(FILE*, int*);
...
    rational* HEAD = read_data(ifp, &sz);

    printf("\nRead Integer Count:%d\n", sz);

    display_values(HEAD);
...
rational* read_data(FILE* fptr, int* size)
{
     *size = 0;
    if (1 != fscanf(fptr, "%d", size)) return NULL;
    rational* ls = malloc(*size * sizeof(rational)); // never cast return value of malloc!

    for (int i = 0; i < *size; i  ) {
        if (2 != fscanf(fptr, "%d%d", &ls[i].numerator, &ls[i].denominator)) {
            free(ls);
            return NULL;
        }
        ls[i].next = ls   i   1;  // by definition same as &(ls[i 1])
    }
    ls[*size - 1].next = NULL;
    return ls;
}

But you should add some error processing for fopen returning NULL or read_data returning NULL (file read error)...

CodePudding user response:

there are multiple problems in your code, I corrected them below in comments:

rational* createList(int data[])
{
    rational *head = NULL;
    rational *temp = NULL;
    rational *p = NULL;
    rational *r = NULL; // this variable is not used
    int count = 0; // I didn't see the purpose of this variable
    
    for (int i = 1; i < 5; i  ) // the 5 is a magic number, 
    {                          //if the input file changes, the code will not run as intended
        temp = (rational*)malloc(sizeof(double)); // space should be allocated for rational type not double type
        temp->numerator = data[i];
        temp->denominator = data[  i];
        
        temp->next = NULL;

        if(head == NULL) 
        {
            count  ;
            head = temp;
            printf("\nHEAD NUMERATOR: %d, HEAD DENOMINATOR: %d\n\n", head->numerator, head->denominator);
        }
        else
        {
            p = head;
            while (p->next != NULL)
            {
                count  ;
                p = p->next;

            }
            p->next = temp;            
        }       
    }
    // the return value for this function is missing.
}

void display_values(rational* HEAD)
{
    rational* o = NULL;
    o = HEAD;
    while(o->next != NULL) // this condition will miss the last node of the linked list
    {
        printf("\n\nNUM: %d, DEN: %d", o->numerator, o->denominator);
        o = o->next;
    }
    
}
  •  Tags:  
  • Related