2008-09-16 125 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; 
}