如何在构建时将文件内容获取到C++字符串中?

4

我有一个在C++中编译的文件,我希望其中有一个字符串其值为编译时文件的内容。

换句话说,我想要#include该文件,但该文件应该被包含在双引号内。

我该如何在C++中实现这一点?

如果该文件的文本中包含双引号,我该如何转义它们?


你可以编写一个修改版的奎因程序;-) http://stackoverflow.com/search?q=quine - James McNellis
5个回答

5

您可以使用xxd -i /tmp/your_file > /tmp/your_file_as_string.c命令,它会为您定义一个字符串字面量:

$ cat /tmp/your_file_as_string.c
unsigned char _tmp_inc[] = {
  0x2e, 0x2f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x6e, 0x65, 0x78, 0x74,
  0x4f, 0x6f, 0x6c, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f,
  ...
  0x74, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x63,
  0x0a
};
unsigned int _tmp_inc_len = 1513;

现在你可以使用定义的字符串。

xxd没有添加终止符0x0,有没有办法让它在字符串末尾添加null? - WilliamKF
2
@WilliamKF:很遗憾,不能直接实现。这个SO上的答案提供了一种方法https://dev59.com/WXRC5IYBdhLWcg3wFdJx - Stephen

2

2

我能想到的唯一方法是在编译之前生成另一个文件。你可以构建一个小型实用程序来为你完成这项任务。该实用程序可以处理双引号,并且你可以在构建文件中在编译之前调用它。


1

一个显而易见(但有点幼稚)的方法是进行系统调用并调用cpp -x c++ file.cpp,然后直接将流的内容读入字符串中,就像您执行任何其他文件读取操作一样。

这将在C++模式下调用C预处理器对file.cpp进行处理,这与运行#include ...完全相同。然后将该值存储在string对象中。


1

请尝试查看一下你的编译器/链接器套件是否有一个名为 bin2obj 的程序。如果存在,它通常可以将任何文件生成一个.o.obj 文件,你可以指示链接器将其链接到你的程序中。(如何完成此步骤取决于构建环境。)

通常情况下,你将最终得到一个或两个符号,可以通过以下方式使其在代码中可见:

extern "C" const char * myFile_start;
extern "C" unsigned int myFile_size;

链接器会确保myFile_start指向文件的开头,而myFile_size则提供文件长度的指示。

符号名称可能会有所变化:您可以使用objdumpnmdumpbin等实用程序(再次取决于编译器/链接器套件)来调查生成的.o.obj文件以查找符号名称(如果它们尚未在您的obj2bin工具文档中记录)。

请注意,这会膨胀可执行文件(通常为.data.rodata部分或等效部分),这可能是某些平台上的问题。

(如果您没有bin2obj,则可以通过在搜索引擎上寻找带有您的编译器/IDE名称的“bin2obj”来找到它。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接