SoupFiend
SoupFiend

Reputation: 1

Reading the files contents to the allocated string

I am trying to read the contents of a file and copy those contents into a string which has dynamic memory. However my program keeps allocating only 8 bytes to x. Ultimately I'm trying to create a general function that can read contents from a file and then return the contents as a char. Any help is appreciated.

char* readFile(unsigned long size, char *fileName) {

FILE *file = fopen(fileName, "r");
int c;
if(file != NULL)
{
    while(c != EOF){ //calculate size of file
        c = fgetc(file); //store character
        size++;
    }
    char *x = (char *)malloc((size) * (sizeof(char))); // Size of x = 8 and I'm not sure why
    rewind(file);
    printf("\n");

    int i = 0;
    while(size - 1 > i){ //Reading the files contents to the allocated string
        c = fgetc(file); //store character
        if(c == EOF){
            break;
        }
        x[i] = c;
        i++;
    }

    fclose(file);
    printf("Done Reading");
 }
else
{
 printf("\nError: Unable to open the file for Reading.\n");
}
rewind(file);
return 0;

}

I get a segmentation fault when I run

char* str = readFile(size, originalFile);

Upvotes: 0

Views: 164

Answers (2)

Zaki
Zaki

Reputation: 107

This is (IMHO) an easier way to find the size of the file:

char *readFile(const char *fileName)
{

    unsigned long size = 0;
    char *x;
    FILE *file = fopen(fileName, "r");
    int c;
    if (file != NULL)
    {
        fseek(file, 0, SEEK_END);            /* SET the position at EOF */
        size = ftell(file);                  /* Record the position at EOF to return size of file */
        rewind(file);                        /* SET position back to Origin */
        printf("size detected %ld\n", size); // reads correct size

        x = (char *)malloc((size) * (sizeof(char)));
        rewind(file);
        printf("\n");

        int i = 0;
        while (size - 1 > i)
        {                    //Reading the files contents to the allocated string
            c = fgetc(file); //store character
            if (c == EOF)
            {
                break;
            }
            x[i] = c;
            i++;
        }

        fclose(file);
        printf("Done Reading\n");
    }
    else
    {
        printf("\nError: Unable to open the file for Reading.\n");
        return NULL;
    }
    rewind(file);

    return x; // * you need to return x not zero
}

Successfully reads the content of the file:

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

int main()
{
    char *data;
    data = readFile("records.txt");
    printf("%s\n", data);
    return 0;
}

Upvotes: 0

Antonin GAVREL
Antonin GAVREL

Reputation: 11219

I would use stat to first get the size of your file

stat() retrieves information about the file pointed to by pathname;

And then I made some tiny modifications to your function to make it work:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

char* readFile(char *fileName) {
    FILE *file;
    struct stat st;

    if (!(file = fopen(fileName, "r")))
        return NULL;
    stat(fileName, &st);
    unsigned long size = st.st_size;
    char *x;
    if (!(x = (char *)malloc((size + 1) * (sizeof(char))))) // Size of x = 8 and I'm not sure why
        return NULL;
    unsigned long i = 0;
    while (i < size) //Reading the files contents to the allocated string
        x[i++] = getc(file);
    x[i] = '\0';
    fclose(file);
    printf("Done Reading\n");
    return x;
}

int main(void) {
    char *fileName = "a.txt";

    char *res = readFile(fileName);
    printf("%s\n", res);
    return 0;
}

Don't forget that in C strings are NULL terminated, you need to malloc size+1 to add the final '\0'.

Upvotes: 2

Related Questions