在可以使用 fopen 访问的 exe 中嵌入文本文件

fob*_*122 5 c++ header

我想将带有一些数据的文本文件嵌入到我的程序中。我们称之为“ data.txt ”。

该文本文件通常加载一个函数,该函数需要文本文件的文件名作为输入,并最终使用 fopen() 调用打开......

FILE* name = fopen("data.txt");
Run Code Online (Sandbox Code Playgroud)

我无法真正更改此功能,并且我希望例程每次运行时都打开同一个文件。我见过有人询问是否将文件嵌入为标题,但似乎我无法在嵌入标题中的文件上调用 fopen() 。

所以我的问题是:有没有办法将文本文件作为可调用文件/变量嵌入到 fopen() 中?

我正在使用 VS2008。

RBe*_*eig 2

是和否。最简单的方法是将文本文件的内容转换为已初始化的数组。

char data_txt[] = {
    'd','a','t','a',' ','g','o','e','s',' ','h','e','r','e', //....
};
Run Code Online (Sandbox Code Playgroud)

这种转换可以通过一个小的 Perl 脚本甚至一个小的 C 程序轻松完成。然后,您编译生成的模块并将其链接到您的程序中。

使此过程更易于使用 Makefile 进行管理的一个老技巧是让脚本将其数据转换为初始化程序的主体并将其写入文件,而无需周围的变量声明甚至大括号。如果data.txt转换为data.inc,那么它的使用方式如下:

char data_txt[] = {
#include "data.inc"
};
Run Code Online (Sandbox Code Playgroud)

更新

在许多平台上,可以将任意数据附加到可执行文件本身。诀窍是在运行时找到它。在可能的平台上,可执行文件将有文件头信息,指示可执行映像的长度。它可用于计算打开fseek()可执行文件进行读取后要使用的偏移量。以可移植的方式做到这一点比较困难,因为甚至可能无法在运行时以可移植的方式了解可执行映像的实际文件名。(提示,argv[0]不需要指向实际的程序。)

如果您无法避免对 的调用fopen(),那么您仍然可以使用此技巧来保留 的内容的副本data.txt,并在运行时将其放回文件中。您甚至可以聪明一点,只在文件丢失时才写入该文件......

如果您可以放弃调用fopen()但仍需要FILE *指向数据,那么如果您愿意快速而宽松地使用 C 运行时库的 stdio 实现,那么这很可能是可能的。在 libc 的 GNU 版本中,类似 和sprintf()的函数sscanf()实际上是通过创建一个“足够真实”的函数来实现的FILE *,该函数可以传递给通用实现(vfprintf()vfscanf()、IIRC)。该伪造的FILE被标记为已缓冲,并将其缓冲区指向用户的缓冲区。使用了一些魔法来确保 stdio 的其余部分不会做任何愚蠢的事情。