In order to read a whole file as a string using standard libraries you have to allocate memory, terminate the string, determine size of the file and size of each element. This could happen with fread until I decided to automatize it using this:

char *readFile (FILE* fp, char *source)
    unsigned long long int size;
    unsigned long long int i = 0;
    int chr;

    fseek(fp, 0L, SEEK_END);
    size = ftell(fp);

    source = calloc(size + 1, sizeof(char));

    fseek(fp, 0, SEEK_SET); // rewind

    while(chr != EOF)
        source[i++] = (chr = fgetc(fp));

    source[size] = '\0';    // Terminate string


1 Answer 1


You let the user pass in a char* but you don't use it. you might as well remove it and declare it as a local variable.

char *readFile (FILE* fp)
    char* source;

Some FILE* won't let you seek to the end (stdin and socket streams for example). You should check the return value of fseek and fall back to the classic fread then realloc, rinse and repeat method on error.

A single fread is more efficient than the repeated fgetc; so you can replace the while with:

int readBytes = fread(source, size, 1, fp);

string[readBytes] = '\0';
  • \$\begingroup\$ How come I don't use it? The string will be copied to the char* destination the user specified. \$\endgroup\$
    – Genis
    Jan 30, 2015 at 9:36
  • \$\begingroup\$ The first thing you do with source is assign a freshly callocated chunk of memory to it. This overwrites the buffer the caller passed in and means that in all cases buffer!=readFile(fp, buffer); \$\endgroup\$ Jan 30, 2015 at 9:39
  • \$\begingroup\$ I don't understand. \$\endgroup\$
    – Genis
    Jan 30, 2015 at 9:42
  • \$\begingroup\$ @Genis For all intents and purposes you ignore the value the caller passed in source. \$\endgroup\$ Jan 30, 2015 at 9:46

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.