سؤال

لدي برنامج C++ يستخدم SQLite.أريد تخزين استعلامات SQL في ملف منفصل - ملف نص عادي، لا ملف التعليمات البرمجية المصدر - ولكن قم بتضمين هذا الملف في الملف القابل للتنفيذ مثل المورد.

(يجب أن يعمل هذا على نظام التشغيل Linux، لذا لا يمكنني تخزينه كمورد فعلي على حد علمي، على الرغم من أن ذلك سيكون مثاليًا إذا كان لنظام التشغيل Windows.)

هل هناك أي طريقة بسيطة للقيام بذلك، أم أنها ستتطلب مني أن أكتب نظام الموارد الخاص بي لنظام التشغيل Linux؟(ممكن بسهولة، ولكن الأمر سيستغرق وقتا أطول بكثير.)

هل كانت مفيدة؟

المحلول

يمكنك استخدام objcopy لربط محتويات الملف برمز يمكن لبرنامجك استخدامه.انظر على سبيل المثال، هنا للمزيد من المعلومات.

نصائح أخرى

يمكنك دائمًا كتابة برنامج صغير أو برنامج نصي لتحويل ملفك النصي إلى ملف رأس وتشغيله كجزء من عملية الإنشاء.

استخدم وحدات الماكرو.من الناحية الفنية سيكون هذا الملف مصدر الرمز الملف لكنه لن يبدو هكذا.مثال:

//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 للقيام بمهمة أخرى والانتهاء منها.

فيما يلي نموذج استخدمناه لدمج الملفات عبر الأنظمة الأساسية.إنها عملية مبسطة جدًا، ولكنها على الأرجح ستعمل من أجلك.

قد تحتاج أيضًا إلى تغيير كيفية التعامل مع خلاصات الأسطر في وظيفة 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;
}

إنه قبيح بعض الشيء، ولكن يمكنك دائمًا استخدام شيء مثل:

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

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

حيث يحتوي query_foo.txt على نص الاستعلام المقتبس.

لقد رأيت أن هذا يتم عن طريق تحويل ملف المورد إلى ملف مصدر C مع تحديد مجموعة أحرف واحدة فقط تحتوي على محتوى ملف المورد بتنسيق سداسي عشري (لتجنب مشاكل الأحرف الضارة).يتم بعد ذلك تجميع الملف المصدر الذي تم إنشاؤه تلقائيًا وربطه بالمشروع.

يجب أن يكون من السهل جدًا تنفيذ المحول إلى ملف C التفريغ لكل ملف مورد أيضًا لكتابة بعض وظائف الواجهة للوصول إلى الموارد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top