Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

embedding a text file in an exe which can be accessed using fopen

Tags:

c++

header

I would like to embed a text file with some data into my program. let's call it "data.txt".

This text file is usually loaded with a function which requires the text file's file name as input and is eventually opened using a fopen() call... some something to the lines of

FILE* name = fopen("data.txt");

I can't really change this function and I would like the routine to open this same file every time it runs. I've seen people ask about embedding the file as a header but it seems that I wouldn't be able to call fopen() on a file that I embed into the header.

So my question is: is there a way to embed a text file as a callable file/variable to fopen()?

I am using VS2008.

like image 789
foboi1122 Avatar asked Nov 25 '22 09:11

foboi1122


1 Answers

Yes and No. The easiest way is to transform the content of the text file into an initialized array.

char data_txt[] = {
    'd','a','t','a',' ','g','o','e','s',' ','h','e','r','e', //....
};

This transformation is easily done with a small perl script or even a small C program. You then compile and link the resulting module into your program.

An old trick to make this easier to manage with a Makefile is to make the script transform its data into the body of the initializer and write it to a file without the surrounding variable declaration or even the curly braces. If data.txt is transformed to data.inc, then it is used like so:

char data_txt[] = {
#include "data.inc"
};

Update

On many platforms, it is possible to append arbitrary data to the executable file itself. The trick then is to find it at run time. On platforms where this is possible, there will be file header information for the executable that indicates the length of the executable image. That can be used to compute an offset to use with fseek() after you have opened the executable file for reading. That is harder to do in a portable way, since it may not even be possible to learn the actual file name of your executable image at run time in a portable way. (Hint, argv[0] is not required to point to the actual program.)

If you cannot avoid the call to fopen(), then you can still use this trick to keep a copy of the content of data.txt, and put it back in a file at run time. You could even be clever and only write the file if it is missing....

If you can drop the call to fopen() but still need a FILE * pointing at the data, then this is likely possible if you are willing to play fast and loose with your C runtime library's implementation of stdio. In the GNU version of libc, functions like sprintf() and sscanf() are actually implemented by creating a "real enough" FILE * that can be passed to a common implementation (vfprintf() and vfscanf(), IIRC). That faked FILE is marked as buffered, and points its buffer to the users's buffer. Some magic is used to make sure the rest of stdio doesn't do anything stupid.

like image 179
RBerteig Avatar answered Dec 05 '22 22:12

RBerteig