চর প্রোগ্রাম হিসাবে সি প্রোগ্রামে একটি পাঠ্য ফাইল "# অন্তর্ভুক্ত করুন" []


130

সংকলন সময়ে সি প্রোগ্রামে একটি সম্পূর্ণ পাঠ্য ফাইলকে স্ট্রিং হিসাবে অন্তর্ভুক্ত করার কোনও উপায় আছে কি?

কিছুটা এইরকম:

  • file.txt যাও:

    This is
    a little
    text file
  • main.c:

    #include <stdio.h>
    int main(void) {
       #blackmagicinclude("file.txt", content)
       /*
       equiv: char[] content = "This is\na little\ntext file";
       */
       printf("%s", content);
    }

একটি ছোট প্রোগ্রাম প্রাপ্ত যা স্টাডাউট "এটি একটি ছোট পাঠ্য ফাইল" এ মুদ্রণ করে

এই মুহুর্তে আমি একটি হ্যাকিশ পাইথন স্ক্রিপ্ট ব্যবহার করেছি, তবে এটি বাট-কুৎসিত এবং কেবল একটি ভেরিয়েবল নামের মধ্যে সীমাবদ্ধ, আপনি কি এটির অন্য উপায়টি বলতে পারেন?


চরের মধ্যে একটি ফাইল পড়ার জন্য এখানে একবার দেখুন []। /programming/410943/reading-a-text-file-into-an-array-in-c এখানে সি প্রিপ্রসেসরের ম্যাক্রোগুলি ব্যবহারের জন্য কিছু টিপস are http://gcc.gnu.org/onlinesocs/cpp/Macros.html
ড্যানিয়েল এ। হোয়াইট

3
আপনি কেন এটা করতে চান? রানটাইমে ফাইল পড়বেন না কেন? (উত্তর: সম্ভবত ফাইলটি রানটাইমের সময় কোথায় ছিল তা জানা শক্ত, বা সম্ভবত ইনস্টল করার জন্য কেবল একটি ফাইল থাকা উচিত))
জনাথন লেফলার

অথবা, সম্ভবত টেক্সট ফাইলটি কেবল সংকলন সময়ে উপলভ্য, যেমন উত্স কোড।
টিএমএস

1
কখনও কখনও আপনি ডেটা বিকাশের সময়ে পৃথক ফাইল হিসাবে অ্যাক্সেস করতে চান তবে সামগ্রীগুলি আপনার বাইনারিতে সংকলন করে। উদাহরণটি একটি আরডুইনোতে একটি ওয়েব সার্ভার চালাচ্ছে যার স্থানীয় স্টোরেজে অ্যাক্সেস নেই। আপনি তাদের এইচটিএমএল ফাইলগুলি সম্পাদনা করতে আলাদা রাখতে চান তবে সংকলনের সময় সেগুলি আপনার উত্সের স্ট্রিং হিসাবে উপস্থিত থাকতে হবে।
জর্ডি

উত্তর:


134

আমি (UNIX util) ব্যবহার করার সুপারিশ করছি xxd যাও এই জন্য। আপনি এটি যেমন ব্যবহার করতে পারেন

$ echo hello world > a
$ xxd -i a

আউটপুট:

unsigned char a[] = {
  0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a
};
unsigned int a_len = 12;

18
কেবলমাত্র একটি দ্রষ্টব্য: xxd দ্বারা নির্মিত চর [] নূরের সমাপ্ত নয়! সুতরাং আমি $ xxd -i <file.txt> file.xxd $ ইকো ', 0' >> ফাইল.এক্সএক্সডি এবং মেইন সিআর ফাইল ফাইল_কন্টিতে [] = {# অন্তর্ভুক্ত "ফাইল.এক্সএক্সডি"};

2
আমি কখনই এক্সএক্সডি সম্পর্কে জানতাম না। এটা অসাধারণ!

1
@ ই এসকে: উত্তরটি সরাসরি xxdবলেছে এটি আউটপুট থেকে । অ্যারের নাম হ'ল ইনপুট ফাইলের নাম। যদি আপনি কোনও ইনপুট ফাইল ব্যবহারের পরিবর্তে ডেটা পাইপ করেন তবে আপনি পরিবর্তে হেক্সাডেসিমাল মানগুলির একটি তালিকা পাবেন (অ্যারের ডিক্লেয়ারেশন বা লেন ভেরিয়েবল ছাড়াই)।
হস্তুরকুন

4
জিএলএসএল শেডারগুলি এম্বেড করার সময় এটি অত্যন্ত কার্যকর।
লাইনলো

5
xxd -i file.txt | sed 's/\([0-9a-f]\)$/\0, 0x00/' > file.h
এক্সএক্সডি

104

প্রশ্নটি সি সম্পর্কে ছিল তবে যদি কেউ সি ++ 11 দিয়ে এটি করার চেষ্টা করে তবে এটি নতুন কাঁচা স্ট্রিং লিটারেলগুলির জন্য অন্তর্ভুক্ত পাঠ্য ফাইলটিতে সামান্য পরিবর্তন করেই করা যেতে পারে :

সি ++ তে এটি করুন:

const char *s =
#include "test.txt"
;

পাঠ্য ফাইলে এটি করুন:

R"(Line 1
Line 2
Line 3
Line 4
Line 5
Line 6)"

সুতরাং কেবলমাত্র ফাইলের শীর্ষে একটি উপসর্গ এবং এটির শেষে একটি প্রত্যয় থাকতে হবে। এর মধ্যে আপনি যা চান তা করতে পারেন, যতক্ষণ আপনার চরিত্রের অনুক্রমের প্রয়োজন হয় না ততক্ষণ কোনও বিশেষ পালানোর প্রয়োজন হয় না )"। এমনকি আপনি যদি নিজের নিজস্ব কাস্টম ডিলিমিটার নির্দিষ্ট করে থাকেন তবে এটি কাজ করতে পারে:

R"=====(Line 1
Line 2
Line 3
Now you can use "( and )" in the text file, too.
Line 5
Line 6)====="

5
ধন্যবাদ, আমি আমার সি ++ 11 কোডে বর্গক্ষেত্রের দীর্ঘ টুকরো টুকরো এম্বেড করতে এখানে প্রস্তাবিত পদ্ধতিটি বেছে নিয়েছি। এটি আমাকে এসকিউএলকে তার নিজের ফাইলগুলিতে পরিষ্কারভাবে আলাদা করতে এবং উপযুক্ত সিনট্যাক্স চেকিং, হাইলাইট ইত্যাদির মাধ্যমে এডিট করার অনুমতি দেয়
YitzikC

1
এটি আমি যা চাই সত্যিই তার কাছাকাছি। বিশেষ করে ব্যবহারকারী নির্ধারিত ডিলিমিটার। খুব দরকারী. আমি আরও একধাপ এগিয়ে যেতে চাই: আপনি যে ফাইলটি অন্তর্ভুক্ত করতে চান তা "(এবং প্রত্যয়)" উপসর্গটি পুরোপুরি সরিয়ে দেওয়ার কোনও উপায় আছে কি? আমি ব্রা.in এবং কেট.in নামে দুটি ফাইলের উপসর্গ এবং প্রত্যয় দিয়ে তাদের সংজ্ঞায়িত করার চেষ্টা করেছি, ব্রা.in, ফাইল.টেক্সট এবং কেট.in কে একে একে অন্তর্ভুক্ত করেছি। কিন্তু কম্পাইলার bra.in (যা শুধু আর হয় বিষয়বস্তুর মূল্যায়ন "() আগের পরবর্তী ফাইলের অন্তর্ভুক্ত তাই এটি নালিশ করবে দয়া করে আমাকে জানি যদি কেউ জানে কিভাবে file.txt যাও থেকে উপসর্গ ও প্রত্যয় যাত্রায় পেতে যাক
টিএমএস

আমি অনুমান করছি যে সি ++ আর "(<নিউলাইন> # অন্তর্ভুক্ত ...)" এর অনুমতি দেবে না? হচ্ছে ফাইল আছে চমৎকার হবে কম্পাইল-টাইম-পাকস্থলিতে গ্রহণ কোনো .. না সবটা এনকোডিং .... অর্থাত সোজা JSON অথবা XML বা CSV বা কি প্রয়োজন হয় না
ব্রায়ান Chrisman

আপনি যদি 1+R"...পরিবর্তে প্রারম্ভিক ডিলিমিটার হিসাবে ব্যবহার করেন R"...এবং এর আগে একটি নতুন লাইন প্রিপেন্ড করেন তবে আপনি কাঁচা আক্ষরিক পাঠকে কিছুটা আরও পঠনযোগ্য করে তুলতে পারেন Line 1। এটি অভিব্যক্তিটিকে অ্যারে থেকে পয়েন্টারে রূপান্তরিত করবে, তবে এটি এখানে আসলেই সমস্যা নয়, যেহেতু আপনি পয়েন্টার শুরু করছেন, অ্যারে নয়।
রুসলান

14

আপনার দুটি সম্ভাবনা রয়েছে:

  1. বাইনারি তথ্যের শুরু এবং শেষের দিকে সঠিক চিহ্ন সহ কোনও ফাইলকে বাইনারি ফাইলে রূপান্তর করতে সংকলক / লিংকার এক্সটেনশনগুলি ব্যবহার করুন। এই উত্তরটি দেখুন: জিএনইউ এলডি লিঙ্কার স্ক্রিপ্টের সাথে বাইনারি ফাইল অন্তর্ভুক্ত করুন
  2. আপনার ফাইলটিকে অক্ষরের ধাপের ক্রমে রূপান্তর করুন যা কোনও অ্যারের সূচনা করতে পারে। নোট আপনি কেবল "" করতে এবং একাধিক লাইন বিস্তৃত করতে পারবেন না। আপনার এই কাজটি করার জন্য একটি লাইন ধারাবাহিকতা অক্ষর ( \), পালানোর "অক্ষর এবং অন্যান্য প্রয়োজন। বাইটসকে একটি সিকোয়েন্সে রূপান্তর করতে কেবল সামান্য প্রোগ্রাম লেখার চেয়ে সহজ '\xFF', '\xAB', ...., '\0'(বা xxdঅন্য উত্তর দ্বারা বর্ণিত ইউনিক্স সরঞ্জামটি ব্যবহার করুন , যদি আপনার কাছে এটি উপলব্ধ থাকে!):

কোড:

#include <stdio.h>

int main() {
    int c;
    while((c = fgetc(stdin)) != EOF) {
        printf("'\\x%X',", (unsigned)c);
    }
    printf("'\\0'"); // put terminating zero
}

(পরীক্ষিত না). তারপরে:

char my_file[] = {
#include "data.h"
};

যেখানে ডেটাচ. দ্বারা তৈরি করা হয়

cat file.bin | ./bin2c > data.h

1
শেষ লাইনটি সম্ভবত পড়া উচিত "বিড়াল file.bin | ./bin2c> data.h" বা "./bin2c <file.bin> data.h"
Hasturkun

বাইনারি থেকে একটি হেক্স ফাইল (উইন্ডোজে) তৈরি করতে আমি কোডেপ্রজেক্ট / টিপস / ৮৪৫৯৩৩/২ ব্যবহার করেছিলাম এবং তারপরে আপনার পরামর্শের পরামর্শটি ব্যবহার করেছি char my_file[] = { #include my_large_file.h };!
কেউ আবার কোথাও

bin2cহয় না ডেবিয়ান এর থেকে হিসাবে একই bin2c hxtools, হুঁশিয়ার
ThorSummoner

অথবা যদি তা না হয়, আবাহন এখন অনেক weirder হল:bin2c -H myoutput.h myinput1.txt myinputN.txt
ThorSummoner

9

ঠিক আছে, ডেইমিনের পোস্ট থেকে অনুপ্রাণিত হয়ে আমি নিম্নলিখিত সহজ উদাহরণটি পরীক্ষা করেছি:

a.data:

"this is test\n file\n"

test.c:

int main(void)
{
    char *test = 
#include "a.data"
    ;
    return 0;
}

gcc -E test.c আউটপুট:

# 1 "test.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "test.c"

int main(void)
{
    char *test =
# 1 "a.data" 1
"this is test\n file\n"
# 6 "test.c" 2
    ;
    return 0;
}

সুতরাং এটি কাজ করছে তবে উদ্ধৃতি চিহ্নগুলি ঘিরে থাকা ডেটা প্রয়োজন।


আমার উত্তরের শেষ অংশে আমি এটিই ইঙ্গিত করছি।
ডেমিন

উদ্ধৃতি, বা যাই হোক না কেন, আমার
ইংরাজিকে

এর জন্য ডেটা সি-পলায়ন করা প্রয়োজন। আমি মনে করি না যে পোস্টটি এটি সন্ধান করছে। এটিতে যদি ম্যাক্রো অন্তর্ভুক্ত থাকে তবে ফাইলটির বিষয়বস্তু সি-এড়িয়ে গেছে, তা ঠিক আছে।
ব্রায়ান ক্রিসম্যান

8

আমি কায়াহারের উত্তর পছন্দ করি। আপনি যদি তবে ইনপুট ফাইলগুলি স্পর্শ করতে না চান এবং আপনি সিএমকে ব্যবহার করছেন তবে আপনি ফাইলটিতে ডিলিমিটার অক্ষর ক্রমগুলি যুক্ত করতে পারেন। নিম্নলিখিত সিএমকে কোড, উদাহরণস্বরূপ, ইনপুট ফাইলগুলি অনুলিপি করে এবং সেগুলি অনুযায়ী তাদের সামগ্রী মোড়ানো:

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)

তারপরে সি ++ এর মধ্যে অন্তর্ভুক্ত করুন:

constexpr char *test =
#include "generated/cool.frag"
;

5

আপনি এটি ব্যবহার করে এটি করতে পারেন objcopy:

objcopy --input binary --output elf64-x86-64 myfile.txt myfile.o

এখন আপনার কাছে একটি অবজেক্ট ফাইল রয়েছে যা আপনি নিজের এক্সিকিউটেবলের সাথে লিঙ্ক করতে পারেন যা থেকে সামগ্রীর সূচনা, শেষ এবং আকারের চিহ্ন রয়েছে myfile.txt


1
আপনি কি আমাদের বলতে পারছেন যে প্রতীক নামগুলি কী হবে?
মার্ক অধ্যায়

@ মার্কসিএইচ: ডক্স অনুসারে প্রতীক নামগুলি ইনপুট ফাইলের নাম থেকে উত্পন্ন হয়।
জন জুইনক

আমি অনুমান করছি যে এটি x86-64 নন মেশিনে কাজ করবে না?
থারস্মমনার


2

আপনার আমার xtrইউটিলিটি দরকার তবে আপনি এটি দিয়ে এটি করতে পারেন bash script। এটি আমি কল একটি স্ক্রিপ্ট bin2inc। প্রথম প্যারামিটারটি ফলাফলের নাম char[] variable। দ্বিতীয় প্যারামিটারটির নাম file। ভেরিয়েবলের নাম হিসাবে include fileফাইলের সামগ্রী এনকোডযুক্ত (ছোট হাতের অক্ষরে hex) দিয়ে আউটপুট সি হয়। char arrayহয় zero terminated, এবং তথ্য দৈর্ঘ্য মধ্যে সংরক্ষিত হয়$variableName_length

#!/bin/bash

fileSize ()

{

    [ -e "$1" ]  && {

        set -- `ls -l "$1"`;

        echo $5;

    }

}

echo unsigned char $1'[] = {'
./xtr -fhex -p 0x -s ', ' < "$2";
echo '0x00'
echo '};';
echo '';
echo unsigned long int ${1}_length = $(fileSize "$2")';'

আপনি এখানে এক্সটিআর পেতে পারেন xtr (অক্ষর এক্সএক্সট্র্যাপলটার) জিপিএলভি 3


2

আপনি যদি কিছু নোংরা কৌশল অবলম্বন করতে ইচ্ছুক হন তবে আপনি কাঁচা স্ট্রিং লিটারেলগুলি এবং #includeনির্দিষ্ট ধরণের ফাইলের জন্য সৃজনশীল পেতে পারেন ।

উদাহরণস্বরূপ, বলুন যে আমি আমার প্রকল্পে এসকিউএলটির জন্য কয়েকটি এসকিউএল স্ক্রিপ্টগুলি অন্তর্ভুক্ত করতে চাই এবং আমি সিনট্যাক্স হাইলাইট করতে চাই তবে কোনও বিশেষ বিল্ড অবকাঠামো চাই না। আমার কাছে এই ফাইলটি থাকতে পারে test.sqlযা এসকিউএলাইটের জন্য বৈধ এসকিউএল যেখানে --একটি মন্তব্য শুরু হয়:

--x, R"(--
SELECT * from TestTable
WHERE field = 5
--)"

এবং তারপরে আমার সি ++ কোডে আমি থাকতে পারি:

int main()
{
    auto x = 0;
    const char* mysql = (
#include "test.sql"
    );

    cout << mysql << endl;
}

আউটপুটটি হ'ল:

--
SELECT * from TestTable
WHERE field = 5
--

বা কোনও ফাইল থেকে কিছু পাইথন কোড অন্তর্ভুক্ত করা test.pyযা বৈধ পাইথন স্ক্রিপ্ট (কারণ #পাইথনে একটি মন্তব্য শুরু passহয় এবং এটি কোনও অপশন নয়):

#define pass R"(
pass
def myfunc():
    print("Some Python code")

myfunc()
#undef pass
#define pass )"
pass

এবং তারপরে সি ++ কোডে:

int main()
{
    const char* mypython = (
#include "test.py"
    );

    cout << mypython << endl;
}

যা আউটপুট দেবে:

pass
def myfunc():
    print("Some Python code")

myfunc()
#undef pass
#define pass

আপনি স্ট্রিং হিসাবে অন্তর্ভুক্ত করতে চাইতে পারেন এমন অন্যান্য বিভিন্ন ধরণের কোডের জন্য অনুরূপ কৌশলগুলি খেলানো সম্ভব উচিত। এটি একটি ভাল ধারণা কিনা তা আমি নিশ্চিত নই। এটি একটি ঝরঝরে হ্যাক ধরনের তবে সম্ভবত বাস্তব উত্পাদন কোড আপনি চান কিছু না। যদিও উইকএন্ড হ্যাক প্রকল্পের জন্য ঠিক আছে।


আমি ওপেনজিএল শেডারগুলি পাঠ্য ফাইলগুলিতেও রাখতে এই পদ্ধতির ব্যবহার করেছি!
ইয়ানো

1

Xxd এর সমস্ত বিরক্তি স্থির করে আমি পাইথন 3 এ xxd পুনরায় প্রয়োগ করেছি:

  • সংশোধন সঠিকতা
  • স্ট্রিং দৈর্ঘ্য ডেটাটাইপ: int → আকার_t
  • নাল সমাপ্তি (আপনি যদি এটি চাইতে পারেন তবে)
  • সি স্ট্রিং সামঞ্জস্যপূর্ণ: unsignedঅ্যারের উপর ড্রপ ।
  • ছোট, পঠনযোগ্য আউটপুট, যেমনটি আপনি এটি লিখতেন: মুদ্রণযোগ্য আসকি হ'ল আউটপুট যেমন হয়; অন্যান্য বাইটগুলি হেক্স-এনকোডযুক্ত।

এখানে স্ক্রিপ্টটি নিজেই ফিল্টার করা হয়েছে, যাতে আপনি এটি দেখতে পারেন তা দেখতে পারেন:

pyxxd.c

#include <stddef.h>

extern const char pyxxd[];
extern const size_t pyxxd_len;

const char pyxxd[] =
"#!/usr/bin/env python3\n"
"\n"
"import sys\n"
"import re\n"
"\n"
"def is_printable_ascii(byte):\n"
"    return byte >= ord(' ') and byte <= ord('~')\n"
"\n"
"def needs_escaping(byte):\n"
"    return byte == ord('\\\"') or byte == ord('\\\\')\n"
"\n"
"def stringify_nibble(nibble):\n"
"    if nibble < 10:\n"
"        return chr(nibble + ord('0'))\n"
"    return chr(nibble - 10 + ord('a'))\n"
"\n"
"def write_byte(of, byte):\n"
"    if is_printable_ascii(byte):\n"
"        if needs_escaping(byte):\n"
"            of.write('\\\\')\n"
"        of.write(chr(byte))\n"
"    elif byte == ord('\\n'):\n"
"        of.write('\\\\n\"\\n\"')\n"
"    else:\n"
"        of.write('\\\\x')\n"
"        of.write(stringify_nibble(byte >> 4))\n"
"        of.write(stringify_nibble(byte & 0xf))\n"
"\n"
"def mk_valid_identifier(s):\n"
"    s = re.sub('^[^_a-z]', '_', s)\n"
"    s = re.sub('[^_a-z0-9]', '_', s)\n"
"    return s\n"
"\n"
"def main():\n"
"    # `xxd -i` compatibility\n"
"    if len(sys.argv) != 4 or sys.argv[1] != \"-i\":\n"
"        print(\"Usage: xxd -i infile outfile\")\n"
"        exit(2)\n"
"\n"
"    with open(sys.argv[2], \"rb\") as infile:\n"
"        with open(sys.argv[3], \"w\") as outfile:\n"
"\n"
"            identifier = mk_valid_identifier(sys.argv[2]);\n"
"            outfile.write('#include <stddef.h>\\n\\n');\n"
"            outfile.write('extern const char {}[];\\n'.format(identifier));\n"
"            outfile.write('extern const size_t {}_len;\\n\\n'.format(identifier));\n"
"            outfile.write('const char {}[] =\\n\"'.format(identifier));\n"
"\n"
"            while True:\n"
"                byte = infile.read(1)\n"
"                if byte == b\"\":\n"
"                    break\n"
"                write_byte(outfile, ord(byte))\n"
"\n"
"            outfile.write('\";\\n\\n');\n"
"            outfile.write('const size_t {}_len = sizeof({}) - 1;\\n'.format(identifier, identifier));\n"
"\n"
"if __name__ == '__main__':\n"
"    main()\n"
"";

const size_t pyxxd_len = sizeof(pyxxd) - 1;

ব্যবহার (এটি স্ক্রিপ্টটি বের করে):

#include <stdio.h>

extern const char pyxxd[];
extern const size_t pyxxd_len;

int main()
{
    fwrite(pyxxd, 1, pyxxd_len, stdout);
}

1

আপনি যদি এমন কিছু করেন তবে কী কাজ হতে পারে :

int main()
{
    const char* text = "
#include "file.txt"
";
    printf("%s", text);
    return 0;
}

অবশ্যই ফাইলের মধ্যে যা আছে তা সম্পর্কে সতর্কতা অবলম্বন করতে হবে , ডাবল উদ্ধৃতি নেই কিনা তা নিশ্চিত করে, সমস্ত উপযুক্ত অক্ষর পালিয়ে গেছে ইত্যাদি।

সুতরাং আপনি যদি রানটাইমের সময় কোনও ফাইল থেকে পাঠ্যটি লোড করেন বা সরাসরি কোডটিতে পাঠ্য এম্বেড করেন তবে এটি আরও সহজ হতে পারে ।

আপনি যদি এখনও অন্য কোনও ফাইলের পাঠ্যটি দেখতে চান তবে এটি এটি সেখানে থাকতে পারে তবে এটি স্ট্রিং হিসাবে সেখানে উপস্থাপন করতে হবে। আপনি উপরের মত কোডটি ব্যবহার করবেন তবে এতে ডাবল উদ্ধৃতি ছাড়াই। উদাহরণ স্বরূপ:

file.txt যাও

"Something evil\n"\
"this way comes!"

main.cpp

int main()
{
    const char* text =
#include "file.txt"
;
    printf("%s", text);
    return 0;
}

সুতরাং মূলত আপনার অন্তর্ভুক্ত একটি পাঠ্য ফাইলে একটি সি বা সি ++ স্টাইলের স্ট্রিং রয়েছে। এটি কোডটি আরও সুন্দর করে তুলবে কারণ ফাইলটির শুরুতে এই বিশাল পাঠ্য নেই।


3
দুর্দান্ত ধারণা তবে এটি কার্যকর হবে না, হয় আপনার একটি ত্রুটি হয়েছে কারণ আক্ষরিক একটি নতুন লাইন রয়েছে বা # অন্তর্ভুক্ত অংশটি স্ট্রিং হিসাবে পড়বে এবং কার্যকর করা হবে না, যদি আপনি করেন তবে নিন্দিত এবং যদি না করেন তবে ধিক্কার দেওয়া হবে .. ।
মোটি

1
@ মোটি: সম্মত - লিখিত হিসাবে, সিনট্যাক্টিকালি অবৈধ সি। ধারণাটি আকর্ষণীয় - সি প্রাক-প্রসেসরটি যৌক্তিকভাবে একটি পৃথক পর্যায় - তবে অনুশীলনটি হ'ল এটি স্থল থেকে নামবে না কারণ অন্তর্ভুক্ত ফাইলের প্রতিটি লাইন থাকবে একটি ব্যাকস্ল্যাশ ইত্যাদির সাথে শেষ করতে
জনাথন লেফলার

2
Humm। আমার কাছে মনে হচ্ছে আপনার ব্যাকস্ল্যাশ দরকার হবে না কারণ বেশিরভাগ সংকলক একসাথে
অ্যাডজেন্ট

এই উত্তরের জিনিসটি হ'ল ... যদি এটি সহজ ছিল তবে আমি মনে করি না যে ওপি কখনও প্রশ্নটি জিজ্ঞাসা করেছিল! -1 কারণ এই উত্তরের উপস্থিতি কিছুটা কাজ করে না এমন চেষ্টা করে তাদের সময় নষ্ট করতে সামান্য উত্সাহ দেয়। আমি মনে করি আপনি "রেফারেন্সের জন্য, এটি কাজ করে না"
মার্ক সিএইচ

@ জোনাথনলফলার প্রিপ্রেসেসর চলার পরে ফাইল. টেক্সট কীভাবে বিন্যাস করা যায় তার উপর নির্ভর করে এটি বৈধ সি বা সি ++ হওয়া উচিত।
দেমিন

0

এমনকি এটি সংকলনের সময়ে করা যেতে পারে (আমি সাধারণভাবে এটি করতে পারি বলে মনে করি না), টেক্সটটি ফাইলগুলির বিষয়বস্তু ভারব্যাটিকের চেয়ে প্রিপ্রোসেসড শিরোনাম হতে পারে। আমি আশা করি রানটাইমের সময় আপনাকে ফাইল থেকে পাঠ্যটি লোড করতে হবে বা একটি কদর্য কাট-এন-পেস্ট কাজ করতে হবে।


0

Xxd -i বিকল্পটি ব্যবহার করে হস্তুরকুনের উত্তরটি দুর্দান্ত। আপনি যদি রূপান্তর প্রক্রিয়াটি (পাঠ্য -> হেক্স ফাইল অন্তর্ভুক্ত) সরাসরি আপনার বিল্ড হেক্সডাম্প.সি. সরঞ্জাম / লাইব্রেরিতে অন্তর্ভুক্ত করতে চান তবে এক্সএক্সডি-আই বিকল্পের মতো সামর্থ্য যুক্ত করেছেন (এটি আপনাকে সম্পূর্ণ শিরোনাম দেয় না - আপনার প্রয়োজন চর অ্যারের সংজ্ঞা প্রদান করতে - তবে এতে আপনার চর অ্যারের নাম বাছাই করার সুবিধা রয়েছে):

http://25thandclement.com/~william/projects/hexdump.c.html

এটির এক্সএক্সডির তুলনায় এটি অনেক বেশি "স্ট্যান্ডার্ড" এবং খুব উদার - এটি কোনও প্রোগ্রামে একটি এনআইডি ফাইল এম্বেড করতে ব্যবহার করার উদাহরণ সিএমকেলিস্ট.টেক্সট এবং স্কিটি। সি ফাইলগুলিতে পাওয়া যেতে পারে:

https://github.com/starseeker/tinyscheme-cmake

উত্স গাছ এবং বান্ডিলিং ইউটিলিটিগুলিতে উত্পন্ন ফাইলগুলি অন্তর্ভুক্ত করার পক্ষে বিভিন্ন উপকারিতা রয়েছে - এটি কীভাবে পরিচালনা করবেন তা আপনার প্রকল্পের নির্দিষ্ট লক্ষ্য এবং প্রয়োজনের উপর নির্ভর করবে। hexdump.c এই অ্যাপ্লিকেশনটির জন্য বান্ডিলিং বিকল্পটি খুলবে।


0

আমি মনে করি একা সংকলক এবং প্রিপ্রোসেসর দিয়ে এটি সম্ভব নয়। জিসিসি এটির অনুমতি দেয়:

#define _STRGF(x) # x
#define STRGF(x) _STRGF(x)

    printk ( MODULE_NAME " built " __DATE__ " at " __TIME__ " on host "
            STRGF(
#               define hostname my_dear_hostname
                hostname
            )
            "\n" );

তবে দুর্ভাগ্যক্রমে এটি নয়:

#define _STRGF(x) # x
#define STRGF(x) _STRGF(x)

    printk ( MODULE_NAME " built " __DATE__ " at " __TIME__ " on host "
            STRGF(
#               include "/etc/hostname"
            )
            "\n" );

ত্রুটিটি হ'ল:

/etc/hostname: In function init_module’:
/etc/hostname:1:0: error: unterminated argument list invoking macro "STRGF"

আমি দেখেছি, আপনি আমাকে যেমন অনুরোধ করলেন তেমন চেহারা। /etc/hostnameস্ট্রিংয়ে বিল্ড মেশিনের নাম এম্বেড করার উপায় হিসাবে কোনও রেফারেন্সের বাইরে আমি আপনার উত্তরে কোনও নতুন তথ্য (অন্য উত্তরগুলিতে নয় এমন তথ্য) দেখতে পাচ্ছি না , যা (এমনকি এটি কাজ করলেও) নাও হবে পোর্টেবল যেহেতু ম্যাক ওএস এক্সের কোনও ফাইল নেই /etc/hostname। নোট করুন যে ম্যাক্রো নামগুলি যা আন্ডারস্কোর দিয়ে শুরু হয় তারপরে একটি বড় অক্ষর অনুসরণ করে প্রয়োগের জন্য সংরক্ষিত একটি নাম ব্যবহার করা হয়, এটি একটি খারাপ জিনিস is ™
জোনাথন লেফলার

0

প্রোগ্রামটিতে পাঠ্যটিকে সংযুক্ত করে বিশ্বব্যাপী ভেরিয়েবল হিসাবে ব্যবহার করবেন না কেন! এখানে একটি উদাহরণ। আমি এক্সিকিউটেবলের মধ্যে ওপেন জিএল শেডার ফাইলগুলি অন্তর্ভুক্ত করার জন্য এটি ব্যবহার করার বিষয়ে বিবেচনা করছি যেহেতু রানটাইম সময়ে জিপিইউয়ের জন্য জিএল শেডারের সংকলন করা প্রয়োজন।


0

আমার একই রকম সমস্যা ছিল এবং ছোট ফাইলগুলির জন্য জোহানেস স্কাউবের পূর্বোক্ত সমাধানটি আমার জন্য কবজির মতো কাজ করেছিল।

তবে যে ফাইলগুলি কিছুটা বড় it অতএব, আমি একটি ছোট এনকোডার অ্যাপ্লিকেশন লিখেছি যা ফাইল সামগ্রীতে সমান আকারের অংশগুলির 2D অক্ষরের অ্যারে রূপান্তর করে (এবং সম্ভবত প্যাডিং জিরো)। এটি 2D অ্যারের ডেটার সাথে আউটপুট পাঠ্য ফাইলগুলি তৈরি করে:

const char main_js_file_data[8][4]= {
    {'\x69','\x73','\x20','\0'},
    {'\x69','\x73','\x20','\0'},
    {'\x61','\x20','\x74','\0'},
    {'\x65','\x73','\x74','\0'},
    {'\x20','\x66','\x6f','\0'},
    {'\x72','\x20','\x79','\0'},
    {'\x6f','\x75','\xd','\0'},
    {'\xa','\0','\0','\0'}};

যেখানে 4 প্রকৃতপক্ষে এনকোডারে MAX_CHARS_PER_ARRAY পরিবর্তনশীল। ফলাফল হিসাবে চিহ্নিত সি কোড সহ ফাইলটি, উদাহরণস্বরূপ "main_js_file_data.h" এর পরে সহজেই সি ++ অ্যাপ্লিকেশনটির মধ্যে অন্তর্ভুক্ত করা যেতে পারে, উদাহরণস্বরূপ:

#include "main_js_file_data.h"

এখানে এনকোডারটির উত্স কোডটি রয়েছে:

#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>


#define MAX_CHARS_PER_ARRAY 2048


int main(int argc, char * argv[])
{
    // three parameters: input filename, output filename, variable name
    if (argc < 4)
    {
        return 1;
    }

    // buffer data, packaged into chunks
    std::vector<char> bufferedData;

    // open input file, in binary mode
    {    
        std::ifstream fStr(argv[1], std::ios::binary);
        if (!fStr.is_open())
        {
            return 1;
        }

        bufferedData.assign(std::istreambuf_iterator<char>(fStr), 
                            std::istreambuf_iterator<char>()     );
    }

    // write output text file, containing a variable declaration,
    // which will be a fixed-size two-dimensional plain array
    {
        std::ofstream fStr(argv[2]);
        if (!fStr.is_open())
        {
            return 1;
        }
        const std::size_t numChunks = std::size_t(std::ceil(double(bufferedData.size()) / (MAX_CHARS_PER_ARRAY - 1)));
        fStr << "const char " << argv[3] << "[" << numChunks           << "]"    <<
                                            "[" << MAX_CHARS_PER_ARRAY << "]= {" << std::endl;
        std::size_t count = 0;
        fStr << std::hex;
        while (count < bufferedData.size())
        {
            std::size_t n = 0;
            fStr << "{";
            for (; n < MAX_CHARS_PER_ARRAY - 1 && count < bufferedData.size(); ++n)
            {
                fStr << "'\\x" << int(unsigned char(bufferedData[count++])) << "',";
            }
            // fill missing part to reach fixed chunk size with zero entries
            for (std::size_t j = 0; j < (MAX_CHARS_PER_ARRAY - 1) - n; ++j)
            {
                fStr << "'\\0',";
            }
            fStr << "'\\0'}";
            if (count < bufferedData.size())
            {
                fStr << ",\n";
            }
        }
        fStr << "};\n";
    }

    return 0;
}

0

এই সমস্যাটি আমাকে বিরক্ত করেছিল এবং এক্সএক্সডি আমার ব্যবহারের ক্ষেত্রে কাজ করে না কারণ এটি স্ক্রিপ্ট করার চেষ্টা করার সময় এটি __home_myname_build_prog_cmakelists_src_autogen এর মতো কিছু পরিবর্তনশীল তৈরি করেছিল, তাই আমি এই সঠিক সমস্যাটি সমাধান করার জন্য একটি ইউটিলিটি তৈরি করেছি:

https://github.com/Exaeta/brcc

এটি একটি উত্স এবং শিরোলেখ ফাইল উত্পন্ন করে এবং আপনাকে প্রতিটি ভেরিয়েবলের নাম সুস্পষ্টভাবে সেট করার অনুমতি দেয় যাতে আপনি সেগুলি স্টাডি :: আরগেন (অ্যারে নাম) এবং স্টাডি :: শেষ (অ্যারে নাম) এর মাধ্যমে ব্যবহার করতে পারেন।

আমি এটিকে আমার চিত্রে প্রজেক্টে অন্তর্ভুক্ত করেছি:

add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/binary_resources.hpp ${CMAKE_CURRENT_BINARY_DIR}/binary_resources.cpp
  COMMAND brcc ${CMAKE_CURRENT_BINARY_DIR}/binary_resources RGAME_BINARY_RESOURCES_HH txt_vertex_shader ${CMAKE_CURRENT_BINARY_DIR}/src/vertex_shader1.glsl
  DEPENDS src/vertex_shader1.glsl)

ছোট টুইটগুলি দিয়ে আমি মনে করি এটি সি এর জন্যও কাজ করা যেতে পারে।


-1

এক্সএইচ

"this is a "
"buncha text"

মেন

#include <stdio.h>
int main(void)
{
    char *textFileContents =
#include "x.h"
    ;

    printf("%s\n", textFileContents);

    return 0
}

কাজ করা উচিত।


"লাইন 1 \ N" "লাইন 2 \ N": একাধিক লাইনের জন্য আপনি এন তাই যোগ করার জন্য \ প্রয়োজন
সুপারফ্লাই জন

এটি কিছুটা বিভ্রান্তিকর, স্পষ্টতই এর জন্য উদ্ধৃতি এবং of n অক্ষর যুক্ত করতে পাঠ্য ফাইলের কিছু প্রস্তুতি দরকার, সাধারণ ক্ষেত্রে কাজ করে না
মার্ক সিএইচ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.