"#include" un archivo de texto en un programa C como carácter[]
¿Hay alguna manera de incluir un archivo de texto completo como una cadena en un programa C en tiempo de compilación?
algo como:
archivo.txt:
This is a little text file
C Principal:
#include <stdio.h> int main(void) { #blackmagicinclude("file.txt", content) /* equiv: char[] content = "This is\na little\ntext file"; */ printf("%s", content); }
obteniendo un pequeño programa que imprime en la salida estándar "Este es un pequeño archivo de texto"
Por el momento utilicé un script de Python hack, pero es feo y está limitado a un solo nombre de variable, ¿puedes decirme otra forma de hacerlo?
Sugeriría usar (unix util) xxd para esto. puedes usarlo así
$ echo hello world > a
$ xxd -i a
salidas:
unsigned char a[] = {
0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a
};
unsigned int a_len = 12;
La pregunta era sobre C, pero en caso de que alguien intente hacerlo con C++ 11, se puede hacer con solo pequeños cambios en el archivo de texto incluido gracias a los nuevos literales de cadena sin formato :
En C++ haz esto:
const char *s =
#include "test.txt"
;
En el archivo de texto haz esto:
R"(Line 1
Line 2
Line 3
Line 4
Line 5
Line 6)"
Por lo que sólo debe haber un prefijo en la parte superior del archivo y un sufijo al final del mismo. Entre ellos puedes hacer lo que quieras, no es necesario ningún escape especial siempre que no necesites la secuencia de caracteres )"
. Pero incluso esto puede funcionar si especifica su propio delimitador personalizado:
R"=====(Line 1
Line 2
Line 3
Now you can use "( and )" in the text file, too.
Line 5
Line 6)====="
Me gusta la respuesta de Kayahr. Sin embargo, si no desea tocar los archivos de entrada y está utilizando CMake , puede agregar las secuencias de caracteres delimitadores en el archivo. El siguiente código CMake, por ejemplo, copia los archivos de entrada y ajusta su contenido en consecuencia:
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)
Luego incluya en c++ así:
constexpr char *test =
#include "generated/cool.frag"
;