是和否。最简单的方法是将文本文件的内容转换为已初始化的数组。
char data_txt[] = {
'd','a','t','a',' ','g','o','e','s',' ','h','e','r','e', //....
};
这种转换可以通过一个小的 Perl 脚本甚至一个小的 C 程序轻松完成。然后,您编译生成的模块并将其链接到您的程序中。
使用 Makefile 使其更易于管理的一个老技巧是让脚本将其数据转换为body的初始化程序并将其写入文件,而无需周围的变量声明甚至大括号。如果data.txt
变换为data.inc
,然后像这样使用:
char data_txt[] = {
#include "data.inc"
};
Update
在许多平台上,可以将任意数据附加到可执行文件本身。诀窍是在运行时找到它。在可能的平台上,可执行文件将有文件头信息,指示可执行映像的长度。可用于计算要使用的偏移量fseek()
打开可执行文件进行读取后。以可移植的方式做到这一点比较困难,因为甚至可能无法在运行时以可移植的方式了解可执行映像的实际文件名。 (暗示,argv[0]
不需要指向实际的程序。)
如果您无法避免致电fopen()
,那么你仍然可以使用这个技巧来保留内容的副本data.txt
,并在运行时将其放回到文件中。您甚至可以聪明一点,只在文件丢失时才写入该文件......
如果您可以挂断电话fopen()
但仍然需要一个FILE *
指向数据,那么这很可能if您愿意随意使用 C 运行时库的 stdio 实现。在 GNU 版本的 libc 中,函数如下sprintf()
and sscanf()
实际上是通过创建一个“足够真实”来实现的FILE *
可以传递给通用实现(vfprintf()
and vfscanf()
,IIRC)。那是伪造的FILE
被标记为已缓冲,并将其缓冲区指向用户的缓冲区。使用了一些魔法来确保 stdio 的其余部分不会做任何愚蠢的事情。