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[]
,运行xxd
到xargs
的输出: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】:使用fopen
、getline
和fclose
。
【讨论】:
相当于 PyRun_File。这个想法是在编译时将它捆绑到可执行文件中,这样我就不必做那种事情了。 这将为您获取执行机器上文件的运行时内容,而不是构建机器上文件的编译时内容。以上是关于C/C++,你能#include一个文件到一个字符串文字中吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
C / C ++如何读取UNICODE的const char?