2008-09-16 122 views
17

我有一个使用SQLite的C++程序。我想将SQL查询存储在一个单独的文件中 - 纯文本文件,而不是的源代码文件 - 但将该文件嵌入可执行文件中,如资源。将数据嵌入到C++程序中

(这有可能在Linux上运行,所以我不能把它存储为一个实际的资源,据我所知,虽然这将是完美的,如果它是适用于Windows)。

有没有什么简单的方法要做到这一点,还是会有效地要求我为Linux编写自己的资源系统? (很容易,但需要更长的时间。)

回答

24

您可以使用objcopy把该文件的内容绑定到符号的程序可以使用。例如,请参阅here了解更多信息。

3

使用宏。从技术上说,该文件将是源代码文件,但它不会看起来像这样。 例子:

//queries.incl - SQL queries 
Q(SELECT * FROM Users) 
Q(INSERT [a] INTO Accounts) 


//source.cpp 
#define Q(query) #query, 
char * queries[] = { 
#include "queries.incl" 
}; 
#undef Q 

后来,你可以做各种其他处理对同一文件的文件,说你会希望有阵列,并将它们的哈希地图,你可以重新定义Q可另做工作,并完成它。

1

这是稍微难看,但你总是可以使用类似:

const char *query_foo = 
#include "query_foo.txt" 

const char *query_bar = 
#include "query_bar.txt" 

凡query_foo.txt将包含引用的查询文本。

+1

如果它包含什么新行? – 2010-11-22 13:23:54

+0

它不适用于换行。 – SmallChess 2015-05-20 06:21:04

3

你总是可以写一个小程序或脚本,以文本文件转换成一个头文件并运行它作为构建过程的一部分。

0

我看这要由资源文件仅与一个字符数组定义包含以十六进制格式资源文件的内容转换为C源文件进行(以避免恶意字符的问题)。这个自动生成的源文件然后被简单编译并链接到项目。

它应该是很容易实现的转换器来转储为每个资源文件还C文件的写一些正面的功能访问的资源。

2

以下是我们用于跨平台嵌入文件的示例。 这很简单,但可能适合你。

你也可能需要改变它是如何处理换行符在escapeLine功能。

#include <string> 
#include <iostream> 
#include <fstream> 
#include <cstdio> 

using namespace std; 

std::string escapeLine(std::string orig) 
{ 
    string retme; 
    for (unsigned int i=0; i<orig.size(); i++) 
    { 
     switch (orig[i]) 
     { 
     case '\\': 
      retme += "\\\\"; 
      break; 
     case '"': 
      retme += "\\\""; 
      break; 
     case '\n': // Strip out the final linefeed. 
      break; 
     default: 
      retme += orig[i]; 
     } 
    } 
    retme += "\\n"; // Add an escaped linefeed to the escaped string. 
    return retme; 
} 

int main(int argc, char ** argv) 
{ 
    string filenamein, filenameout; 

    if (argc > 1) 
     filenamein = argv[ 1 ]; 
    else 
    { 
     // Not enough arguments 
     fprintf(stderr, "Usage: %s <file to convert.mel> [ <output file name.mel> ]\n", argv[0]); 
     exit(-1); 
    } 

    if (argc > 2) 
     filenameout = argv[ 2 ]; 
    else 
    { 
     string new_ending = "_mel.h"; 
     filenameout = filenamein; 
     std::string::size_type pos; 
     pos = filenameout.find(".mel"); 
     if (pos == std::string::npos) 
      filenameout += new_ending; 
     else 
      filenameout.replace(pos, new_ending.size(), new_ending); 
    } 

    printf("Converting \"%s\" to \"%s\"\n", filenamein.c_str(), filenameout.c_str()); 

    ifstream filein(filenamein.c_str(), ios::in); 
    ofstream fileout(filenameout.c_str(), ios::out); 

    if (!filein.good()) 
    { 
     fprintf(stderr, "Unable to open input file %s\n", filenamein.c_str()); 
     exit(-2); 
    } 
    if (!fileout.good()) 
    { 
     fprintf(stderr, "Unable to open output file %s\n", filenameout.c_str()); 
     exit(-3); 
    } 

    // Write the file. 
    fileout << "tempstr = "; 

    while(filein.good()) 
    { 
     string buff; 
     if (getline(filein, buff)) 
     { 
      fileout << "\"" << escapeLine(buff) << "\"" << endl; 
     } 
    } 

    fileout << ";" << endl; 

    filein.close(); 
    fileout.close(); 

    return 0; 
}