C/C++, можете ли вы #включить файл в строковый литерал?[дубликат]

StackOverflow https://stackoverflow.com/questions/1246301

Вопрос

На этот вопрос уже есть ответ здесь:

У меня есть исходный файл C++ и исходный файл Python.Я бы хотел, чтобы исходный файл C++ мог использовать содержимое исходного файла Python как большой строковый литерал.Я мог бы сделать что-то вроде этого:

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

Но это не сработает, потому что в конце каждой строки должны быть символы \.Я мог бы вручную скопировать и вставить содержимое кода Python и заключить каждую строку в кавычки и завершающий , но это некрасиво.Несмотря на то, что исходный код Python будет эффективно скомпилирован в мое приложение на C++, я бы хотел сохранить его в отдельном файле, поскольку он более организован и лучше работает с редакторами (emacs недостаточно умен, чтобы распознать, что С строковый литерал представляет собой код Python и переключается в режим Python, пока вы внутри него).

Пожалуйста, не предлагайте мне использовать PyRun_File, это то, чего я стараюсь избегать в первую очередь;)

Это было полезно?

Решение

Препроцессор C/C++ действует в единицах токенов, а строковый литерал представляет собой одинокий жетон.Таким образом, вы не можете вмешаться в середину строкового литерала таким образом.

Вы можете предварительно обработать script.py во что-то вроде:

"some code\n"
"some more code that will be appended\n"

и #include, однако.Или вы можете использовать xxd​ -i для создания статического массива C, готового к включению.

Другие советы

Это не приведет вас к цели до конца, но это подведет вас чертовски близко.

Предполагая 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"
;

Вероятно, есть еще более жесткий ответ, чем этот, но я все еще ищу.

Лучший способ сделать что-то подобное - включить файл в качестве ресурса, если ваша среда / набор инструментов имеет такую возможность.

Если нет (например, встроенные системы и т.д.), вы можете использовать утилиту bin2c (что-то вроде http://stud3.tuwien.ac.at /~e0025274/bin2c/bin2c.c).Он примет двоичное представление файла и выдаст исходный файл C, который включает массив байтов, инициализированных для этих данных.Возможно, вам потребуется выполнить некоторую настройку инструмента или выходного файла, если вы хотите, чтобы массив заканчивался '\0'.

Включите запуск утилиты bin2c в свой makefile (или как этап предварительной сборки всего, что вы используете для управления своими сборками).Затем просто скомпилируйте файл и свяжите его с вашим приложением, и ваша строка (или любой другой образ файла) будет храниться в фрагменте памяти, представленном массивом.

Если вы включаете текстовый файл в виде строки, вам следует знать о том, что окончания строк могут не соответствовать ожидаемым функциями - возможно, это еще одна вещь, которую вы хотели бы добавить в утилиту bin2c, или вы захотите убедиться, что ваш код правильно обрабатывает все окончания строк в файле.Возможно, измените утилиту bin2c, установив переключатель '-s', который указывает, что вы хотите, чтобы текстовый файл был представлен в виде строки, чтобы окончания строк были нормализованы, а нулевой байт находился в конце массива.

Вам придется выполнить некоторую собственную обработку кода Python, чтобы справиться с любыми двойными кавычками, обратной косой чертой, триграфами и, возможно, другими вещами, которые появляются в нем.Вы можете одновременно преобразовать новые строки в (или экранировать их обратной косой чертой) и добавить двойные кавычки с обоих концов.Результатом будет файл заголовка, сгенерированный из исходного файла Python, который затем вы можете #включить.Используйте свой процесс сборки, чтобы автоматизировать это, чтобы вы все еще могли редактировать исходный код Python как Python.

Вы могли бы использовать Винтик как часть вашего процесса сборки (для выполнения предварительной обработки и встраивания кода).Я признаю, что результат этого, вероятно, не идеален, поскольку в конечном итоге вы видите код в обоих местах.Но каждый раз, когда я вижу "Python", "C ++" и "Препроцессор" в непосредственной близости, я чувствую, что это заслуживает упоминания.

Вот как автоматизировать преобразование с помощью 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);

Это довольно системно-зависимый подход, но, как и большинству людей, мне не понравился шестнадцатеричный дамп.

Использование fopen, getline, и fclose.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top