0

I'm wondering if anyone can help me with my below code. I'm struggling to implement dynamic allocation for my program when reading data from a file and storing it in a struct. I'm new to both structs and dynamic allocation. While my program seems to be storing the data successfully into the struct I can see in Visual Studio that the allocation of these is not correct. Any advice on storing the data dynamic would be much appreciated. I was trying to use malloc but could not get this to work for me.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void load_data();


typedef struct {
    char name[12];
    char vaccinevendor[8];
    char vaccinationdate[12];
    char dob[12];
    char underlyingcond[8];
    char id[7];
}  Record;



int main(void)
{

    load_data();

    return 0;
}

void load_data()
{
    
    Record s1[2];


    FILE* Ptr;  /*file pointer*/

    if ((Ptr = fopen("records.txt", "rb")) == NULL) {
        printf("File does not exist\n");
    
        Ptr = fopen("records.txt", "w");
        if (Ptr != NULL)
            printf("records.txt file has now been created.\n");
        else {
            printf("Unable to create file!\n");
            return 1;
        }
    }


     Ptr = (char*)malloc(1000 * sizeof(char));

    // read file contents till end of file
    fread(&s1, sizeof(Record), 2, Ptr);
    
    fclose(Ptr); /*close stream*/

}

Hi all,

As per my comment below I have updated my code but am getting errors when trying to store my array strings into my struct. As I was asked in the comments also, the test file contents are lines in the following format:

John Smith
Pfizer
02/08/2021
06/01/1990
None
556679

Mary Jones
None
None
09/10/1988
Asthma
556677
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 13
#define stringlen 15
#define numoflines 12

void load_data();


typedef struct {
    char name[12];
    char vaccinevendor[8];
    char vaccinationdate[12];
    char dob[12];
    char underlyingcond[8];
    char id[7];
}  Record;



int main(void)
{

    load_data();

    return 0;
}

void load_data()
{
    char line[110], buff[13][50];
    int len;
    int i = 0;

    Record s1[2];


    FILE* Ptr;  /*file pointer*/

    if ((Ptr = fopen("records.txt", "rb")) == NULL) {
        printf("File does not exist\n");
    
        Ptr = fopen("records.txt", "w");
        if (Ptr != NULL)
            printf("records.txt file has now been created.\n");
        else {
            printf("Unable to create file!\n");
            return 1;
        }
    }

    for (i = 0; i < SIZE; ++i)
    {
        len = strlen(buff[i]);
        fgets(buff[i], 21, Ptr);
        s1[0] = malloc(len);
        strcpy(s1[i], buff);
    }

    fclose(Ptr); /*close stream*/

}
11
  • 1
    As an aside, your void function should not return a return value... Commented Jan 12, 2022 at 11:12
  • Ptr = (char*)malloc(1000 * sizeof(char)); . Ptr is not of type char *. You should create a new varaible for this. You also can't close a char pointer. Commented Jan 12, 2022 at 11:13
  • Please edit and show the first 5-6 lines of record.txt. As it's name suggsts, it's a text file, therefore fread is wrong. This SO question deals with that problem. Commented Jan 12, 2022 at 11:20
  • Also it's very unclear what you're trying to do. Please edit and show the requirements. Commented Jan 12, 2022 at 11:22
  • "Any advice on ..." --> Yes. Enable all warnings. Then your compiler will give you quicker feedback than posting on SO. Example "warning: 'return' with a value, in function returning void [-Wreturn-type]", return 1; "warning: assignment to 'FILE *' from incompatible pointer type 'char *' [-Wincompatible-pointer-types]" Ptr = (char*) malloc(1000 * sizeof(char)); Commented Jan 12, 2022 at 13:37

2 Answers 2

1

Correcting the obvious error

// Ptr = (char*)malloc(1000 * sizeof(char));

// read file contents till end of file
fread(&s1, sizeof(Record), 2, Ptr);

fclose(Ptr); /*close stream*/

the commented out line is clearly thinking it neeeds to 'allocate a buffer' in some way. No, s1 is the buffer, and you certainly never want to change Ptr (its the pointer to the internals of the file system).

However this code almost certainly wont work unless your file is very precisely laid out. For example it needs to start like this (in hex)

4141414100000000000000004242420000000000

if the fist name is "AAAA" and the first vendor is "BBB". And even then it might not work due to struct padding issues

Sign up to request clarification or add additional context in comments.

Comments

0

Your code does not really make sense. Ptr points to the file opened through fopen which is fine. But then you allocate dynamic memory (through malloc) and assign the adress of this memory to the same Ptr. So basically you have lost the previous value of Ptr, in other terms the reference to your file (not to mention Ptr is of type FILE * and you assign to it a char *).

You don't need to allocate memory for Ptr, you need to allocate memory for the buffer where you copy data from this file. But here s1 is located on the stack, you don't need dynamic memory allocation.

Also be careful when copying raw data to a struct. Data structures may have "holes" in between their fields depending on data alignement (here as you have only chararrays, all the fields are probably contiguous).

I suggest you learn about data structures and the different kinds of memory allocation in C.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.