This question already has an answer here:
I want to write the full contents of a file into a buffer. The file actually only contains a string which i need to compare with a string.
What would be the most efficient option which is portable even on linux.
ENV: Windows
Portability between Linux and Windows is a big headache, since Linux is a POSIX-conformant system with - generally - a proper, high quality toolchain for C, whereas Windows doesn't even provide a lot of functions in the C standard library.
However, if you want to stick to the standard, you can write something like this:
Here
string
will contain the contents of the text file as a properly 0-terminated C string. This code is just standard C, it's not POSIX-specific (although that it doesn't gurantee it will work/compile on Windows...)A portable solution could use
getc
.If you don't want to have a
MAX_FILE_SIZE
macro or if it is a big number (such thatbuffer
would be to big to fit on the stack), use dynamic allocation.If you know the maximum buffer size ahead of time:
Or, if you don't know it:
Here is what I would recommend.
It should conform to C89, and be completely portable. In particular, it works also on pipes and sockets on POSIXy systems.
The idea is that we read the input in large-ish chunks (
READALL_CHUNK
), dynamically reallocating the buffer as we need it. We only userealloc()
,fread()
,ferror()
, andfree()
:Above, I've used a constant chunk size,
READALL_CHUNK
== 262144 (256*1024
). This means that in the worst case, up to 262145 chars are wasted (allocated but not used), but only temporarily. At the end, the function reallocates the buffer to the optimal size. Also, this means that we do four reallocations per megabyte of data read.The 262144-byte default in the code above is a conservative value; it works well for even old minilaptops and Raspberry Pis and most embedded devices with at least a few megabytes of RAM available for the process. Yet, it is not so small that it slows down the operation (due to many read calls, and many buffer reallocations) on most systems.
For desktop machines at this time (2017), I recommend a much larger
READALL_CHUNK
, perhaps#define READALL_CHUNK 2097152
(2 MiB).Because the definition of
READALL_CHUNK
is guarded (i.e., it is defined only if it is at that point in the code still undefined), you can override the default value at compile time, by using (in most C compilers)-DREADALL_CHUNK=2097152
command-line option -- but do check your compiler options for defining a preprocessor macro using command-line options.