'Read null characters from file into string

I have created a function where I can read the first x amount of bytes from a file. The file is a binary file, and contains NULL characters. I am trying to read the file into a char* however it gives an incorrect length because I am appending NULL characters to the string. Is there a workaround to storing data from a file in a string

    // readlen is the amount I want to read from the start of a file

    FILE* fptr = fopen(path, "rb");

    char* contents = (char*)malloc(readlen + 1);
    int read = 0;
    int ch;

    while ((ch = fgetc(fptr)) != EOF && read != readlen) {
        contents[read++] = (char)ch;
    }

    contents[readlen] = '\0';
    fclose(fptr);
    return contents;


Solution 1:[1]

First, a terminology misconception in the title "Read null characters from file into string". In C, string can not contain NUL characters, because those mark end of the string. A char buffer can contain them, but it's not a string. And when it is not a string with an end marker, you need to keep track of its length.


Then, to solve your problem, you could return a struct with the information

struct buffer {
    char *contents;
    size_t size;
};

With that, the code you show becomes something like this:

// readlen is the amount I want to read from the start of a file

FILE* fptr = fopen(path, "rb");

struct buffer buffer;
buffer.contents = (char*)malloc(readlen + 1);
buffer.size = 0;
int ch;

while ((ch = fgetc(fptr)) != EOF && buffer.size != readlen) {
    buffer.contents[buffer.size++] = (char)ch;
}

buffer.contents[buffer.size] = '\0';
fclose(fptr);
return buffer;

Further improvement of your function would be to use fread to do the read with one function call. You might discover, that your own function becomes unnecessary and you could just directly call fread, even.

Also, putting extra 0 at the end of the char buffer might not be useful, since it is not a string, but it doesn't really hurt and will be convenient if you ever read a text file and want to print it or something. Still, unless you have some specific need for it, I'd consider removing that extra byte.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1