C/C++,你能#include一个文件到一个字符串文字中吗? [复制]

Posted

技术标签:

【中文标题】C/C++,你能#include一个文件到一个字符串文字中吗? [复制]【英文标题】:C/C++, can you #include a file into a string literal? [duplicate] 【发布时间】:2010-11-17 19:02:23 【问题描述】:

我有一个 C++ 源文件和一个 Python 源文件。我希望 C++ 源文件能够将 Python 源文件的内容用作大字符串文字。我可以这样做:

char* python_code = "
#include "script.py"
"

但这行不通,因为每行的末尾都需要有 \'s。我可以手动复制和粘贴 Python 代码的内容,并用引号和终止的 \n 将每一行括起来,但这很难看。即使 python 源代码将被有效地编译到我的 C++ 应用程序中,我还是想将它保存在一个单独的文件中,因为它更有条理并且与编辑器一起工作更好(emacs 不够聪明,无法识别 C 字符串文字是 Python 代码,当你在其中时切换到 Python 模式)。

请不要建议我使用 PyRun_File,这是我首先要避免的;)

【问题讨论】:

如果是重复的,你能提供一个链接吗?我环顾四周,没有看到任何与我的搜索字词有关的内容。 另外,以前的版本是 python 特定的吗?因为这是一个更笼统的问题。 顺便说一句,嵌入 python 脚本是不好的形式,除非它非常微不足道。工作中的人这样做,当我们在python环境中更改内容时会导致各种问题,但是因为它在.cpp文件中而错过了更新他们的代码! 这很简单,它们是单元测试的一部分。 有趣的是,链接到重复的问题是针对 C 的,但最佳答案是针对 C++11 的。 :-/ 【参考方案1】:

C/C++ 预处理器以记号为单位进行操作,字符串文字是一个单个 记号。因此,您不能像这样干预字符串文字的中间。

您可以将 script.py 预处理为:

"some code\n"
"some more code that will be appended\n"
但是,

和 #include 。或者您可以使用xxd​ -i 生成一个准备包含的 C 静态数组。

【讨论】:

+1 表示 xxd。脚本可能不需要是字符串文字。 你如何预处理 script.py 呢?我看不出有办法用 CPP 做到这一点。除非你的意思是在那个实例中也使用像 sed 这样的外部工具。 一个外部工具,是的。你不能只用 CPP 做你想做的事。 对于那些打开了-Wall -Wextra 的人,使用此技巧生成文件并将值分配给const char[],运行xxdxargs 的输出:xxd -i some-file.txt | xargs printf "(char)%s"。它不漂亮,但它有效。【参考方案2】:

这不会让你一直到那里,但它会让你非常接近。

假设script.py 包含这个:

print "The current CPU time in seconds is: ", time.clock()

首先,把它包起来:

STRINGIFY(print "The current CPU time in seconds is: ", time.clock())

然后,在包含它之前,执行以下操作:

#define STRINGIFY(x) #x

const char * script_py =
#include "script.py"
;

可能还有比这更严格的答案,但我仍在寻找。

【讨论】:

你先生,吃饼干吧! 2 年围绕这个问题跳舞 我有一个(肯定很少见的)案例,我有时需要包含与代码相同的文件,有时需要包含一个字符串(不要问;))。所以我在包含的文件中添加了#ifndef STRINGIFY \n #define STRINGIFY(x) x \n #endif,当我想将它作为代码包含时,我确保没有定义 STRINGIFY。奇迹般地它也适用于多行文件! 我认为这个答案比公认的答案更有帮助,但它还没有完全到位。它仍然需要对包含的文件进行一些修改。我想知道是否有人找到了任何解决方法?【参考方案3】:

如果您的环境/工具集具有该功能,则执行此类操作的最佳方法是将文件作为资源包含在内。

如果不是(如嵌入式系统等),您可以使用 bin2c 实用程序(类似于http://stud3.tuwien.ac.at/~e0025274/bin2c/bin2c.c)。它将采用文件的二进制表示并输出一个 C 源文件,其中包含一个初始化为该数据的字节数组。如果您希望数组被 '\0' 终止,您可能需要对工具或输出文件进行一些调整。

将运行 bin2c 实用程序合并到您的 makefile 中(或作为您用于驱动构建的任何内容的预构建步骤)。然后只需编译文件并将其与您的应用程序链接,您的字符串(或文件的任何其他图像)就位于由数组表示的一块内存中。

如果您将文本文件作为字符串包含在内,您应该注意的一件事是行尾可能与预期的函数不匹配 - 这可能是您想要添加到 bin2c 实用程序或您的另一件事'将要确保您的代码正确处理文件中的任何行结尾。也许修改 bin2c 实用程序以具有一个“-s”开关,表示您希望将文本文件合并为字符串,以便行尾将被规范化,并且零字节将位于数组的末尾。

【讨论】:

文件的链接已失效。你有副本吗?【参考方案4】:

您将不得不对 Python 代码进行一些自己的处理,以处理其中出现的任何双引号、反斜杠、三元组以及可能的其他内容。您可以同时将换行符转换为 \n (或反斜杠转义它们)并在两端添加双引号。结果将是从 Python 源文件生成的头文件,然后您可以#include。使用您的构建过程自动执行此操作,以便您仍然可以将 Python 源代码编辑为 Python。

【讨论】:

【参考方案5】:

您可以使用Cog 作为构建过程的一部分(进行预处理和嵌入代码)。我承认这样做的结果可能并不理想,因为你最终会在两个地方看到代码。但是,每当我看到“Python”、“C++”和“预处理器”接近时,我觉得它值得一提。

【讨论】:

【参考方案6】:

这是使用 cmd.exe 自动转换的方法

------html2h.bat ------

@echo off
echo const char * html_page = "\
sed "/.*/ s/$/ \\n\\/" ../src/page.html | sed s/\"/\\\x22/g 
echo.
echo ";

它被称为

cmd /c "..\Debug\html2h.bat" > "..\debug\src\html.h"

并通过

附加到代码中
#include "../Debug/src/html.h"
printf("%s\n", html_page);

这是相当依赖于系统的方法,但和大多数人一样,我不喜欢十六进制转储。

【讨论】:

【参考方案7】:

使用fopengetlinefclose

【讨论】:

相当于 PyRun_File。这个想法是在编译时将它捆绑到可执行文件中,这样我就不必做那种事情了。 这将为您获取执行机器上文件的运行时内容,而不是构建机器上文件的编译时内容。

以上是关于C/C++,你能#include一个文件到一个字符串文字中吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

C/C++ 字符串分割

C / C ++如何读取UNICODE的const char?

C语言 文件读写 fgetc 函数

这段代码在做啥。检查两个字符串的字谜

用C/C++写一个字符串GBK转UTF-8编码的函数,并写main函数测试(在线等)

C/c++中如何产生指定的随机字符