Error reading a file and saving it in dynamically allocated space in c

Asked

Viewed 33 times

1

I want to create a program that:

  1. Opens the file teste

  2. I figured out the size of this file

  3. Allocate enough memory space for file + 1 (\0)

  4. Read the file contents using the function fread and saved in the allocated location

  5. Prints the read content

But when I run the program it prints a lot of random characters as if it were converting a random number into ascii-code

I know that fread() is not the most efficient way, more is just a test for a real problem in a larger source code and I deduced that the problem would be a similar part

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

int main(void)
{
    FILE *file;
    int FileSize;
    int result;
    char *c;
    
    file = fopen("P:\\teste", "r");
    
    fseek(file, 0, SEEK_END);
    FileSize = ftell(file);
    
    c = (char *) malloc((FileSize+1) * sizeof(char));
    
    result = fread(c, sizeof(char), FileSize, file);
    printf("%s", c);
    
    free(c);
    fclose(file);
    return(0);
}

1 answer

2

The problem is that fseek(file, 0, SEEK_END) arrow the position to the end of the file. Then the fread starts reading from there, but as it is already at the end of the file, there is nothing more to read.

So you need to go back to the beginning of the file before reading. And you also have to remember to add the terminator at the end of the string:

fseek(file, 0, SEEK_SET); // volta para o início do arquivo
fread(c, 1, FileSize, file); // lê tudo
c[FileSize] = '\0'; // adiciona o terminador

Remembering that sizeof(char) always is 1, then you can use 1 direct, fearless.


Another detail is that you don’t have to do cast in the malloc, then it might just be:

c = malloc(FileSize + 1);

And in fact, you don’t have to declare all the variables at the beginning and only then use them in the course of the program (this was true in the past, but I don’t know why there are people who still use - and some even teach - like this). You can declare a variable at the time it is used. That is to say:

FILE *file = fopen("arquivo.txt", "r");

fseek(file, 0, SEEK_END);
int FileSize = ftell(file);
char *c = malloc(FileSize + 1);

fseek(file, 0, SEEK_SET);
fread(c, 1, FileSize, file);
c[FileSize] = '\0';

Remember also that in a more serious code you should check the return of all functions: fread returns the amount that was read, so you can compare with FileSize to know if everything has been successfully read; ftell returns -1L (the "L" indicates that it is a long) in case of error, fopen returns a null pointer if any error occurs while opening the file, etc.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.