有没有办法在编译时将整个文本文件作为字符串包含在C程序中?
就像是:
file.txt的:
This is a little text file
main.c中:
#includeint main(void) { #blackmagicinclude("file.txt", content) /* equiv: char[] content = "This is\na little\ntext file"; */ printf("%s", content); }
获取一个在stdout上打印的小程序"这是一个小文本文件"
目前我使用了一个hackish python脚本,但它只是丑陋而且仅限于一个变量名,你能告诉我另一种方法吗?
我建议使用(unix util)xxd.你可以像这样使用它
$ echo hello world > a $ xxd -i a
输出:
unsigned char a[] = { 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a }; unsigned int a_len = 12;
问题是关于C但是如果有人试图用C++ 11做,那么只需对包含的文本文件进行少量更改就可以完成,这要归功于新的原始字符串文字:
在C++中这样做:
const char *s = #include "test.txt" ;
在文本文件中执行以下操作:
R"(Line 1 Line 2 Line 3 Line 4 Line 5 Line 6)"
因此,文件顶部必须只有一个前缀,并且文件末尾只有一个后缀.在它之间你可以做你想要的,只要你不需要字符序列就不需要特殊的转义)"
.但是,如果您指定自己的自定义分隔符,即使这样也可以:
R"=====(Line 1 Line 2 Line 3 Now you can use "( and )" in the text file, too. Line 5 Line 6)====="
你有两种可能性:
利用编译器/链接器扩展将文件转换为二进制文件,并使用适当的符号指向二进制数据的开头和结尾.请参阅以下答案:使用GNU ld链接描述文件包含二进制文件.
将文件转换为可以初始化数组的字符常量序列.请注意,您不能只执行""并跨越多行.你需要一个行继续符(\
),转义"
字符和其他来使它工作.更容易编写一个小程序将字节转换为类似的序列'\xFF', '\xAB', ...., '\0'
(或使用xxd
另一个答案描述的unix工具,如果你有它!):
码:
#includeint main() { int c; while((c = fgetc(stdin)) != EOF) { printf("'\\x%X',", (unsigned)c); } printf("'\\0'"); // put terminating zero }
(未经测试).然后做:
char my_file[] = { #include "data.h" };
data.h由哪里生成
cat file.bin | ./bin2c > data.h
好吧,受到Daemin的帖子的启发,我测试了以下简单的例子:
a.data:
"this is test\n file\n"
test.c的:
int main(void) { char *test = #include "a.data" ; return 0; }
gcc -E test.c输出:
# 1 "test.c" # 1 "" # 1 " " # 1 "test.c" int main(void) { char *test = # 1 "a.data" 1 "this is test\n file\n" # 6 "test.c" 2 ; return 0; }
所以它工作但需要用引号括起来的数据.
我喜欢卡亚尔的回答。但是,如果您不想触摸输入文件,并且正在使用CMake,则可以在文件上添加分隔符字符序列。例如,以下CMake代码复制输入文件并相应地包装其内容:
function(make_includable input_file output_file) file(READ ${input_file} content) set(delim "for_c++_include") set(content "R\"${delim}(\n${content})${delim}\"") file(WRITE ${output_file} "${content}") endfunction(make_includable) # Use like make_includable(external/shaders/cool.frag generated/cool.frag)
然后包含在c ++中,如下所示:
constexpr char *test = #include "generated/cool.frag" ;