2008-09-16 12 views
17

Tôi có một chương trình C++ sử dụng SQLite. Tôi muốn lưu trữ các truy vấn SQL trong một tệp riêng biệt - một tệp văn bản thuần túy, không phải là tệp mã nguồn - nhưng nhúng tệp đó vào tệp thi hành như một tài nguyên.Nhúng dữ liệu vào chương trình C++

(Điều này có chạy trên Linux, vì vậy tôi không thể lưu trữ nó như là một nguồn tài nguyên thực tế như xa như tôi biết, mặc dù đó sẽ là hoàn hảo nếu nó là dành cho Windows.)

Có cách nào đơn giản để làm điều đó, hay nó sẽ yêu cầu tôi viết hệ thống tài nguyên của riêng mình cho Linux? (Dễ dàng có thể, nhưng sẽ mất nhiều thời gian hơn.)

Trả lời

24

Bạn có thể sử dụng objcopy để ràng buộc nội dung của tệp với ký hiệu mà chương trình của bạn có thể sử dụng. Xem, ví dụ: here để biết thêm thông tin.

+0

Đẹp! Cảm ơn bạn! –

3

Sử dụng macro. Về mặt kỹ thuật, tệp đó sẽ là mã nguồn tệp nhưng sẽ không giống như thế này. Ví dụ:

//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 

Sau đó bạn có thể làm tất cả các loại chế biến khác trên tập tin đó bằng cách cùng một tập tin, nói bạn muốn có mảng và một bản đồ băm trong số họ, bạn có thể xác định lại Q để làm khác công việc và được thực hiện với nó.

1

Nó hơi xấu xí, nhưng bạn luôn có thể sử dụng một cái gì đó như:

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

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

đâu query_foo.txt sẽ chứa nội dung truy vấn niêm yết.

+1

nếu nó có dòng mới thì sao? –

+0

Nó sẽ không hoạt động cho một dòng mới. – SmallChess

3

Bạn luôn có thể viết một chương trình hoặc tập lệnh nhỏ để chuyển đổi tệp văn bản của mình thành tệp tiêu đề và chạy nó như là một phần của quá trình xây dựng.

0

Tôi đã thấy điều này được thực hiện bằng cách chuyển đổi tệp tài nguyên thành tệp nguồn C chỉ có một mảng char được xác định chứa nội dung tệp tài nguyên theo định dạng thập lục phân (để tránh các vấn đề với ký tự độc hại). Tệp nguồn được tạo tự động này sau đó được biên dịch và liên kết đơn giản với dự án. Nó sẽ khá dễ dàng để thực hiện chuyển đổi để đổ tập tin C cho mỗi tập tin tài nguyên cũng như để viết một số chức năng mặt tiền để truy cập các nguồn tài nguyên.

2

Đây là mẫu mà chúng tôi đã sử dụng để nhúng các tệp đa nền tảng. Nó khá đơn giản, nhưng có lẽ sẽ làm việc cho bạn.

Bạn cũng có thể cần thay đổi cách xử lý dòng dữ liệu trong hàm 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; 
}