সি এনুম থেকে মান পরিবর্তে পাঠ্য মুদ্রণ করুন


89

আপনার প্রত্যাশিত আউটপুটটি "রবিবার" ইত্যাদি স্ট্রিং প্রিন্ট করার জন্য?
গ্যালাকটিক কাউবয়

উত্তর:


104

সি তে গণনাগুলি এমন একটি সংখ্যা যা আপনার কোডের অভ্যন্তরে সুবিধাজনক নাম রাখে। সেগুলি স্ট্রিং নয় এবং সোর্স কোডে তাদের অর্পিত নামগুলি আপনার প্রোগ্রামে সংকলিত হয় না এবং তাই রানটাইম এ সেগুলি অ্যাক্সেসযোগ্য হয় না।

আপনি যা চান তা পাওয়ার একমাত্র উপায় হ'ল একটি ফাংশন নিজেই লিখুন যা গণনার মানকে স্ট্রিংয়ে অনুবাদ করে। উদাহরণস্বরূপ (এখানে ধরে নিচ্ছেন যে আপনি এর ঘোষণাপত্রের enum Daysবাইরে চলেছেন main):

বিকল্পভাবে, আপনি মানচিত্র হিসাবে কোনও অ্যারে ব্যবহার করতে পারেন, যেমন

তবে এখানে আপনি সম্ভবত Sunday = 0নিরাপদ হিসাবে গণনাটি নির্ধারণ করতে চান ... আমি নিশ্চিত নই যে সি স্ট্যান্ডার্ডকে 0 থেকে গণনা শুরু করা দরকার কিনা, যদিও বেশিরভাগই করেন (আমি নিশ্চিত কেউ এটি নিশ্চিত বা অস্বীকার করার জন্য মন্তব্য করবেন )।


4
ওহ, আপনি আমাকে অ্যারে সমাধানটিতে মারধর করেছেন। : পি তবে হ্যাঁ, এনামগুলি সর্বদা 0 থেকে শুরু হয় যদি না আপনি আলাদা মান উল্লেখ করেন।
ক্যাসাব্ল্যাঙ্কা

4
যদি আমি সূচী হিসাবে তালিকাটি ব্যবহারের উপর নির্ভর করে থাকি তবে আমি প্রকৃতপক্ষে প্রতিটিকেই স্পষ্টভাবে সংখ্যায়িত করতে পছন্দ করব। মান অনুসারে অপ্রয়োজনীয়, কিন্তু গোষ্ঠী সংকলক হিসাবে আমার অভিজ্ঞতায় নিম্নলিখিত মানগুলি যথাযথভাবে হয়নি।
jdmichal

4
সি স্ট্যান্ডার্ডটি বলে, "যদি প্রথম গণকের কোনও = থাকে তবে তার গণনার ধ্রুবকের মান 0 হয়"। তবে এটি স্পষ্টভাবে জানাতে কোনও ক্ষতি করে না।
মাইকেল বুড়

17
C99 দিয়ে আপনি এটি করতে পারেন তা ভুলে যাবেন না const char* dayNames[] = {[Sunday] = "Sunday", [Monday] = "Monday", [Tuesday] = "Tuesday", /* ... etc ... */ };। আপনি জানেন, যদি সপ্তাহের দিনগুলি পুনরায় সাজানো হয় বা আপনি ঠিক করেন যে সোমবার সপ্তাহের প্রথম দিন।
টিম শ্যাফার

4
@ ব্যবহারকারী 3467349 এটি (প্রিপ্রোসেসর স্ট্রিংফিকেশন) কেবল # টি অনুসরণ করে প্রতীকটিকে একটি স্ট্রিংয়ে পরিণত করে। সুতরাং, হ্যাঁ, # সোমবার "সোমবার" এ পরিণত Days TheDay = Monday; printf("%s", #TheDay);হবে তবে "থেডে" মুদ্রণ করবে।
টাইলার ম্যাকহেনরি

29

আমি এই জাতীয় কিছু ব্যবহার:

"EnumToString.h" ফাইলটিতে:

তারপরে যে কোনও শিরোনাম ফাইলে আপনি এনাম ঘোষণা, দিন এনুম

তারপরে EnumToString.c নামে একটি ফাইলে:

তারপরে মেন।

এটি যে কোনও এনামের জন্য এভাবে ঘোষণা করা এবং "EnumToString.c" এ অন্তর্ভুক্ত থাকবে তার জন্য "স্বয়ংক্রিয়ভাবে" স্ট্রিং উত্পন্ন করবে


4
এটি পড়তে কুৎসিত, তবে আপনার কাছে ডেটা নকল নেই। (অন্য সবার মতো নয়) এটি পছন্দ করতে হবে কিনা তা নিয়ে আমি ছিঁড়ে গিয়েছি।
কিম রিস

4
কোনও ডেটা অনুলিপি এবং সম্ভবত সেরা রক্ষণাবেক্ষণ / নমনীয়তা না দিয়ে দুর্দান্ত সৃজনশীল সমাধানের জন্য +1! আমি মনে করি আমি তবুও কেবল কনস্ট চর * [] পথে যেতে চাই।
প্রকাশিত

4
হ্যাঁ, রক্ষণাবেক্ষণ দুর্দান্ত! সপ্তাহের দিনগুলি পরিবর্তিত হলে এটি আপডেট করা সত্যিই সহজ! <<<<<<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< কমপক্ষে অন্যান্য পদ্ধতির সাথে, উত্স ফাইলগুলিতে প্রতিটি ঘটনা পরিবর্তন না করে স্ট্রিংগুলির অনুবাদ করা সম্ভব।
আর .. গীটহাব বন্ধ করুন ICE

4
আপনি সম্ভবত এটি (গেটেক্সটসের মতো কিছু দিয়ে) রিটার্নের স্টেটমেন্ট return _(#element)এবং এর মতো পরিবর্তন করে আন্তর্জাতিককরণ করতে পারেন।
ভার্গাস

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

7

আমি সাধারণত যেভাবে এটি করি তা হ'ল স্ট্রিং উপস্থাপনাগুলি একই ক্রমে পৃথক অ্যারেতে সংরক্ষণ করা, তারপরে এনাম মান দিয়ে অ্যারেটিকে সূচীকরণ করা:


4

enumসি তে এস আপনি যেভাবে প্রত্যাশা করছেন বাস্তবে সেভাবে কাজ করবেন না। আপনি এগুলি সম্পর্কে গৌরবযুক্ত ধ্রুবকগুলির মতো ( যেমন ধ্রুবকগুলির সংগ্রহ সম্পর্কিত কয়েকটি অতিরিক্ত সুবিধা সহ) ভাবতে পারেন এবং "রবিবার" এর জন্য আপনি যে পাঠ্যটি লিখেছেন তা সংকলনের সময় একটি সংখ্যায় সত্যিই সমাধান হয়ে যায়, পাঠ্যটি হ'ল শেষ পর্যন্ত বাতিল।

সংক্ষেপে: আপনি যা করতে চান তা করতে আপনাকে স্ট্রিংগুলির একটি অ্যারে রাখতে হবে বা এনামের মান থেকে আপনি যে পাঠ্যটি মুদ্রণ করতে চান তাতে মানচিত্র তৈরি করতে একটি ফাংশন তৈরি করতে হবে।


4

সি-তে গণনাগুলি মূলত স্বয়ংক্রিয়ভাবে সিকোয়েন্সড পূর্ণসংখ্যার মানগুলির তালিকাভুক্ত তালিকাগুলির জন্য সিনট্যাকটিকাল চিনি। এটি যখন আপনার এই কোডটি থাকে:

আপনার সংকলক আসলে এটি ছিটকে:

অতএব, একটি স্ট্রিং হিসাবে একটি সি গণনার আউটপুট আউটপুট একটি ক্রিয়াকলাপটি বোঝায় যে ক্রিয়াকলাপ নয়। আপনি যদি এগুলির জন্য মানব-পঠনযোগ্য স্ট্রিং রাখতে চান, তবে আপনাকে অঙ্কগুলি থেকে স্ট্রেনে রূপান্তর করতে ফাংশনগুলি সংজ্ঞায়িত করতে হবে।


4

ম্যাক্রোগুলির সাহায্যে এটি করার একটি পরিষ্কার উপায়:

আমি নিশ্চিত নই যে এটি সম্পূর্ণ পোর্টেবল বি / ডাব্লু প্রিপ্রসেসর, তবে এটি জিসিসির সাথে কাজ করে।

এটি সি 99 বিটিডাব্লু , সুতরাং c99 strictআপনি যদি এটি (অনলাইন সংকলক) আইডিয়োনে প্লাগ করেন তবে ব্যবহার করুন ।


"পরিষ্কার" ম্যাক্রোগুলি কীভাবে ভালবাসবে তা :-)।
এম কে 12

3

আমি জানি আমি পার্টিতে দেরি করছি, তবে এ কেমন?

এইভাবে, আপনাকে ম্যানুয়ালি enumএবং char*অ্যারে সিঙ্কে রাখতে হবে না । আপনি যদি আমার মতো হন তবে সম্ভাবনা হ'ল আপনি পরে পরিবর্তন করবেন enumএবং char*অ্যারে অবৈধ স্ট্রিংগুলি মুদ্রণ করবে। এটি সর্বজনীনভাবে সমর্থিত কোনও বৈশিষ্ট্য নাও হতে পারে। তবে আফিক, মোর্ডারন ডে সি সংকলকগুলির বেশিরভাগই এই মনোনীত প্রাথমিক শৈলী সমর্থন করে support

আপনি এখানে মনোনীত প্রাথমিক সম্পর্কে আরও পড়তে পারেন ।


1

প্রশ্ন আপনি নামটি একবার লিখতে চান?
আমার এই মত একটি আইডার আছে:

#define __ENUM(situation,num) \
    int situation = num;        const char * __##situation##_name = #situation;

    const struct {
        __ENUM(get_other_string, -203);//using a __ENUM Mirco make it ease to write, 
        __ENUM(get_negative_to_unsigned, -204);
        __ENUM(overflow,-205);
//The following two line showing the expanding for __ENUM
        int get_no_num = -201;      const char * __get_no_num_name = "get_no_num";
        int get_float_to_int = -202;        const char * get_float_to_int_name = "float_to_int_name";

    }eRevJson;
#undef __ENUM
    struct sIntCharPtr { int value; const char * p_name; };
//This function transform it to string.
    inline const char * enumRevJsonGetString(int num) {
        sIntCharPtr * ptr = (sIntCharPtr *)(&eRevJson);
        for (int i = 0;i < sizeof(eRevJson) / sizeof(sIntCharPtr);i++) {
            if (ptr[i].value == num) {
                return ptr[i].p_name;
            }
        }
        return "bad_enum_value";
    }

এটি এনাম sertোকানোর জন্য একটি কাঠামো ব্যবহার করে, যাতে স্ট্রিং থেকে প্রিন্টার প্রতিটি এনাম মান সংজ্ঞায়িত করতে পারে।

int main(int argc, char *argv[]) {  
    int enum_test = eRevJson.get_other_string;
    printf("error is %s, number is %d\n", enumRevJsonGetString(enum_test), enum_test);

>error is get_other_string, number is -203

এনামের মধ্যে পার্থক্যটি হ'ল বিল্ডার যদি সংখ্যাগুলি পুনরাবৃত্তি করে তবে ত্রুটিটি রিপোর্ট করতে পারে না। আপনি যদি লেখার নম্বর পছন্দ না করেন তবে __LINE__এটি প্রতিস্থাপন করতে পারেন:

#define ____LINE__ __LINE__
#define __ENUM(situation) \
    int situation = (____LINE__ - __BASELINE -2);       const char * __##situation##_name = #situation;
constexpr int __BASELINE = __LINE__;
constexpr struct {
    __ENUM(Sunday);
    __ENUM(Monday);
    __ENUM(Tuesday);
    __ENUM(Wednesday);
    __ENUM(Thursday);
    __ENUM(Friday);
    __ENUM(Saturday);
}eDays;
#undef __ENUM
inline const char * enumDaysGetString(int num) {
    sIntCharPtr * ptr = (sIntCharPtr *)(&eDays);
    for (int i = 0;i < sizeof(eDays) / sizeof(sIntCharPtr);i++) {
        if (ptr[i].value == num) {
            return ptr[i].p_name;
        }
    }
    return "bad_enum_value";
}
int main(int argc, char *argv[]) {  
    int d = eDays.Wednesday;
    printf("day %s, number is %d\n", enumDaysGetString(d), d);
    d = 1;
    printf("day %s, number is %d\n", enumDaysGetString(d), d);
}

>day Wednesday, number is 3 >day Monday, number is 1


0

আমি এটিতে নতুন তবে একটি সুইচ স্টেটমেন্ট অবশ্যই কাজ করবে en


উত্তরের
ভারব্যাটিম

0

আমি দিনের নামগুলিতে এনাম রাখা পছন্দ করি। টাইপিং হ্রাস করতে, আমরা নিম্নলিখিতটি করতে পারি:


0

আরও একটি সমাধান রয়েছে: আপনার নিজস্ব গতিশীল গণনা শ্রেণি তৈরি করুন। মানে structএকটি নতুন অঙ্ক তৈরির জন্য আপনার একটি এবং কিছু ফাংশন রয়েছে যা উপাদানগুলিকে একটিতে রাখে structএবং প্রতিটি উপাদানটির নামের জন্য একটি স্ট্রিং থাকে। আপনার পৃথক উপাদানগুলি সংরক্ষণ করতে কিছু প্রকারের প্রয়োজন, সেগুলির সাথে তুলনা করার জন্য বিভিন্ন ক্রিয়াকলাপ। এখানে একটি উদাহরণ:

গণনার কার্যগুলি তাদের নিজস্ব অনুবাদ ইউনিটে হওয়া উচিত, তবে আমি এগুলিকে এখানে আরও সহজ করে তুলতে সম্মিলিত করেছি।

সুবিধাটি হ'ল এই সমাধানটি নমনীয়, ডিআরওয়াই নীতি অনুসরণ করে, আপনি প্রতিটি উপাদান সহ তথ্য সংরক্ষণ করতে পারেন, রানটাইমের সময় আপনি নতুন গণনা তৈরি করতে পারেন এবং রানটাইমের সময় আপনি নতুন উপাদান যুক্ত করতে পারেন। অসুবিধাটি হ'ল এটি জটিল, গতিশীল মেমরি বরাদ্দ প্রয়োজন, এতে ব্যবহার করা যায় না switch- caseআরও মেমরি দরকার এবং ধীর হয়। প্রশ্নটি হ'ল যদি আপনার এটির প্রয়োজন হয় তবে আপনার উচ্চ স্তরের ভাষা ব্যবহার করা উচিত নয়।


-3

TheDay কিছু পূর্ণসংখ্যার প্রকারে ফিরে আসে। সুতরাং:

স্ট্রিং হিসাবে থেডে পার্স করার চেষ্টা করছে এবং তা হয় আবর্জনা বা ক্র্যাশ ছাপবে।

প্রিন্টফ টাইপসেফ নয় এবং আপনাকে এটির সঠিক মানটি দেওয়ার জন্য বিশ্বাস করে। মানটির নাম মুদ্রণ করতে আপনার এনাম মানকে একটি স্ট্রিংয়ে ম্যাপিংয়ের জন্য কিছু পদ্ধতি তৈরি করতে হবে - হ'ল লুক টেবিল, জায়ান্ট সুইচ বিবৃতি ইত্যাদি either

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.