मैं एक `स्विच` स्टेटमेंट का उपयोग करके सी में तार की तुलना कैसे कर सकता हूं?


84

सी में एक switchनिर्माण होता है जो एक परीक्षण पूर्णांक मान के आधार पर कोड की विभिन्न सशर्त शाखाओं को निष्पादित करने में सक्षम बनाता है, उदाहरण के लिए;

int a;
/* Read the value of "a" from some source, e.g. user input */
switch (a) {
  case 100:
    // Code
    break;
  case 200:
    // Code
    break;
  default:
    // Code
    break;
}

एक स्ट्रिंग मान के लिए समान व्यवहार (यानी तथाकथित " if- elseसीढ़ी" से बचें ) कैसे प्राप्त करना संभव है char *?


"स्विच ऑन" से आपका क्या मतलब है?
kennytm

कृपया सुधार करें ताकि यह प्रश्न स्पष्ट हो जाए कि आप वास्तव में क्या करने की कोशिश कर रहे हैं (या पूछ रहे हैं)।
13:मोन टोह

8
ओपी शायद एक स्विच स्टेटमेंट के पैरामिटर के रूप में एक स्ट्रिंग का उपयोग करना चाहता है। जहां तक ​​मुझे पता है, यह संभव नहीं है।
dandan78

जवाबों:


101

अगर आपका मतलब है, कुछ इसी तरह लिखना:

// switch statement
switch (string) {
  case "B1": 
    // do something
    break;
  /* more case "xxx" parts */
}

फिर सी में विहित समाधान एक-और सीढ़ी का उपयोग करना है:

if (strcmp(string, "B1") == 0) 
{
  // do something
} 
else if (strcmp(string, "xxx") == 0)
{
  // do something else
}
/* more else if clauses */
else /* default: */
{
}

1
दरअसल, समस्या यह है कि मेरे पास पहले से ही इंट पर स्विच है और एक विशेष मामले में मेरे पास "बी 1" और "बी 2" का मूल्य है जिसे मैं उसी स्विच में उपयोग करना चाहता हूं। एकमात्र तरीका यह है कि किसी भी तरह "बी 1" और "बी 2" मूल्यों को परिवर्तित करें और उन्हें इंट के रूप में उपयोग करें !!
निकोलस

2
@ निक्लेस: यह आपके प्रश्न के लिए महत्वपूर्ण जानकारी है। क्या आप अपने प्रश्न को अपडेट कर सकते हैं और समझा सकते हैं (यदि कुछ (छद्म-) कोड के साथ संभव है) तो आप क्या करने की कोशिश कर रहे हैं?
बार्ट वैन इनगेन शानौ

4
@ निक्लेस: आपको अपने प्रश्न को स्पष्ट करना चाहिए: पृथ्वी पर "बी 1" और "बी 2" एक विशेष मामला कैसे हो सकता है?
एडगर बोनट

1
#define A 1 #define B 2 #define C S1 #define D S2 और ये मान वो हैं जो मैं अपने स्विच में उपयोग करना चाहता हूं। इतना सरल :-)
निकोलस

5
@ निक्लेस: परिभाषित तार नहीं हैं। यदि परिभाषित संख्या के लिए है, तो आप इसे इस तरह सीधे अपने स्विच में उपयोग कर सकते हैं switch (something) { case A: /*...*/ break; case B: /*...*/ break; }
बार्ट वैन इनगेन शेनौ

45

यदि आपके पास कई मामले हैं और एक टन strcmp()कॉल लिखना नहीं चाहते हैं, तो आप कुछ ऐसा कर सकते हैं:

switch(my_hash_function(the_string)) {
    case HASH_B1: ...
    /* ...etc... */
}

आपको बस यह सुनिश्चित करना है कि आपके हैश फ़ंक्शन में स्ट्रिंग के लिए संभावित मानों के सेट के अंदर कोई टक्कर नहीं है।


8
"सुनिश्चित करें कि आपके हैश फ़ंक्शन में स्ट्रिंग के लिए संभावित मानों के सेट के अंदर कोई टक्कर नहीं है।" - इस तरह के हैश फ़ंक्शन वर्णमाला के लिए मौजूद है [a-zA-Z0-9_]? कोई उदाहरण?
अरुण

8
@ArunSaha: जाहिर है ऐसे पात्रों के मनमाने संयोजन के लिए नहीं ।
एडगर बोनट

3
यदि आप निश्चित लंबाई स्ट्रिंग कुंजी का उपयोग करते हैं, तो आप उन्हें प्रत्येक को अद्वितीय पूर्णांक में बदल सकते हैं; कोई टक्कर संभव नहीं है।
इंजीनियर

@ArcaneEngineer उम ... क्या यह सटीक समस्या हल करने का प्रयास नहीं है? कैसे, केवल स्ट्रिंग को देखते हुए, आप इसके साथ जाने के लिए एक पूर्णांक निकालेंगे? "एक स्विच का उपयोग करें या अगर / और सीढ़ी" या शायद आप 4 वर्णों की तरह बहुत कम मतलब है?
ebyrob

@ebyrob का मतलब था कि एक त्वरित सेशन में तुलनीय कुछ भी, जैसे कि 2 64-बिट uintएस जिनके बिट्स को 8 1-बाइट ASCII chars के रूप में माना जाता है । मैंने इसे कुछ समय पहले कार्यान्वित किया था, सी। में एक हैश टेबल के भीतर महत्वपूर्ण तुलना के लिए। आप इस प्रकार किसी भी हैशिंग या बाल्टी की आवश्यकता को मिटा देते हैं। समस्या आती है जहां आपको 64 बिट्स से अधिक की आवश्यकता होती है; आप तब शर्तों के लिए लागत का भुगतान करते हैं जब आप charपूर्ण स्ट्रिंग में 8 एस के प्रत्येक सेट पर लूप करते हैं । जब तक आप लूप को अनियंत्रित नहीं करते, अगर आपको चाबियों का अधिकतम आकार पता है। यह एक अच्छा संतुलन वाला अभिनय है।
इंजीनियर

39

सी। में ऐसा करने का कोई तरीका नहीं है। बहुत सारे दृष्टिकोण हैं। आमतौर पर सबसे आसान यह है कि स्थिरांक का एक सेट परिभाषित करें जो आपके तार का प्रतिनिधित्व करता है और निरंतर प्राप्त करने के लिए स्ट्रिंग द्वारा एक नज़र रखता है:

#define BADKEY -1
#define A1 1
#define A2 2
#define B1 3
#define B2 4

typedef struct { char *key; int val; } t_symstruct;

static t_symstruct lookuptable[] = {
    { "A1", A1 }, { "A2", A2 }, { "B1", B1 }, { "B2", B2 }
};

#define NKEYS (sizeof(lookuptable)/sizeof(t_symstruct))

int keyfromstring(char *key)
{
    int i;
    for (i=0; i < NKEYS; i++) {
        t_symstruct *sym = lookuptable[i];
        if (strcmp(sym->key, key) == 0)
            return sym->val;
    }
    return BADKEY;
}

/* ... */
switch (keyfromstring(somestring)) {
case A1: /* ... */ break;
case A2: /* ... */ break;
case B1: /* ... */ break;
case B2: /* ... */ break;
case BADKEY: /* handle failed lookup */
}

बेशक, ऐसा करने के लिए अधिक कुशल तरीके हैं। यदि आप अपनी कुंजियों को क्रमबद्ध रखते हैं, तो आप एक द्विआधारी खोज का उपयोग कर सकते हैं। आप एक हैशटेबल का भी उपयोग कर सकते हैं। ये चीजें रखरखाव की कीमत पर आपके प्रदर्शन को बदल देती हैं।


7
कुंजी के लिए #defines के सेट के बजाय एक एनुम का उपयोग करने के लिए बहुत अच्छा है, लेकिन अन्यथा सबसे अच्छा आप कर सकते हैं।
क्रेग रिंगर

वेतन वृद्धि गलत है। दिखने योग्य + i * आकार (t_symstruct) देखने योग्य [i] के बराबर नहीं है।
asdf

@asdf कि पॉइंटर अंकगणित कैसे काम करता है c। आकार का निहितार्थ है।

20

ऐसा करने के लिए मेरा पसंदीदा तरीका एक हैश फ़ंक्शन ( यहाँ से उधार लिया गया ) है। यह आपको चार्ज स्टेटमेंट की दक्षता का उपयोग करने की अनुमति देता है, जबकि चार * के साथ काम करते समय:

#include "stdio.h"

#define LS 5863588
#define CD 5863276
#define MKDIR 210720772860
#define PWD 193502992

const unsigned long hash(const char *str) {
    unsigned long hash = 5381;  
    int c;

    while ((c = *str++))
        hash = ((hash << 5) + hash) + c;
    return hash;
}

int main(int argc, char *argv[]) {
    char *p_command = argv[1];
    switch(hash(p_command)) {
    case LS:
        printf("Running ls...\n");
        break;
    case CD:
        printf("Running cd...\n");
        break;
    case MKDIR:
        printf("Running mkdir...\n");
        break;
    case PWD:
        printf("Running pwd...\n");
        break;
    default:
        printf("[ERROR] '%s' is not a valid command.\n", p_command);
    }
}

बेशक, इस दृष्टिकोण की आवश्यकता है कि सभी संभव स्वीकृत चार * के लिए हैश मूल्यों की गणना अग्रिम में की जाती है। मुझे नहीं लगता कि यह बहुत अधिक मुद्दा है; हालांकि, स्विच स्टेटमेंट की परवाह किए बिना निश्चित मूल्यों पर काम करता है। हैश फंक्शन के माध्यम से चार * पास करने के लिए एक सरल कार्यक्रम बनाया जा सकता है और उनके परिणामों को आउटपुट कर सकता है। इन परिणामों को तब मैक्रोज़ के माध्यम से परिभाषित किया जा सकता है जैसा कि मैंने ऊपर किया है।


ढेर अतिप्रवाह में आपका स्वागत है। आपने जो दिखाया है वह अच्छी तरह से प्रस्तुत किया गया है और एक अच्छा विचार है, लेकिन ... लेकिन यह बिल्कुल नहीं है कि कुछ अन्य उत्तरों से विशिष्ट रूप से अलग है - ऐसे कई हैं जो इस विचार पर मामूली वेरिएंट का उपयोग करते हैं। यदि आप एक पुराने स्थिर प्रश्न का नया उत्तर जोड़ते हैं, तो आपको बहुत अच्छी जानकारी होनी चाहिए। यह ज्यादातर सावधानी का एक शब्द है; मैं निश्चित रूप से इस बारे में आपको वोट देने के लिए नहीं हूं।
जोनाथन लेफ़लर

16

मुझे लगता है कि ऐसा करने का सबसे अच्छा तरीका कार्यक्षमता से 'मान्यता' को अलग करना है:

struct stringcase { char* string; void (*func)(void); };

void funcB1();
void funcAzA();

stringcase cases [] = 
{ { "B1", funcB1 }
, { "AzA", funcAzA }
};

void myswitch( char* token ) {
  for( stringcases* pCase = cases
     ; pCase != cases + sizeof( cases ) / sizeof( cases[0] )
     ; pCase++ )
  {
    if( 0 == strcmp( pCase->string, token ) ) {
       (*pCase->func)();
       break;
    }
  }

}

8

मैंने सी में स्ट्रिंग्स पर स्विच करने के लिए एक हेडर फ़ाइल प्रकाशित की है । इसमें मैक्रो का एक सेट है जो स्विच-जैसे व्यवहार की नकल करने के लिए कॉल को strcmp () या (इसी तरह) में छिपाता है। मैंने इसे केवल लिनक्स में जीसीसी के साथ परीक्षण किया है, लेकिन मुझे पूरा यकीन है कि इसे अन्य पर्यावरण का समर्थन करने के लिए अनुकूलित किया जा सकता है।

संपादित करें: अनुरोध के अनुसार यहां कोड जोड़ा गया

यह हेडर फ़ाइल है जिसमें आपको शामिल होना चाहिए:

#ifndef __SWITCHS_H__
#define __SWITCHS_H__

#include <string.h>
#include <regex.h>
#include <stdbool.h>

/** Begin a switch for the string x */
#define switchs(x) \
    { char *__sw = (x); bool __done = false; bool __cont = false; \
        regex_t __regex; regcomp(&__regex, ".*", 0); do {

/** Check if the string matches the cases argument (case sensitive) */
#define cases(x)    } if ( __cont || !strcmp ( __sw, x ) ) \
                        { __done = true; __cont = true;

/** Check if the string matches the icases argument (case insensitive) */
#define icases(x)    } if ( __cont || !strcasecmp ( __sw, x ) ) { \
                        __done = true; __cont = true;

/** Check if the string matches the specified regular expression using regcomp(3) */
#define cases_re(x,flags) } regfree ( &__regex ); if ( __cont || ( \
                              0 == regcomp ( &__regex, x, flags ) && \
                              0 == regexec ( &__regex, __sw, 0, NULL, 0 ) ) ) { \
                                __done = true; __cont = true;

/** Default behaviour */
#define defaults    } if ( !__done || __cont ) {

/** Close the switchs */
#define switchs_end } while ( 0 ); regfree(&__regex); }

#endif // __SWITCHS_H__

और यह आप इसे कैसे उपयोग करते हैं:

switchs(argv[1]) {
    cases("foo")
    cases("bar")
        printf("foo or bar (case sensitive)\n");
        break;

    icases("pi")
        printf("pi or Pi or pI or PI (case insensitive)\n");
        break;

    cases_re("^D.*",0)
        printf("Something that start with D (case sensitive)\n");
        break;

    cases_re("^E.*",REG_ICASE)
        printf("Something that start with E (case insensitive)\n");
        break;

    cases("1")
        printf("1\n");
        // break omitted on purpose

    cases("2")
        printf("2 (or 1)\n");
        break;

    defaults
        printf("No match\n");
        break;
} switchs_end;

मैंने एक "ब्रेक" को जोड़कर उदाहरण का संपादन नहीं किया, लेकिन इस तथ्य को उजागर करते हुए कि आप इसे छोड़ सकते हैं
एंड्रिया कैरन

1
यह अच्छा है! इससे पहले कि मैं "sscanf" का उपयोग मैच के लिए करूं, "regex.h" सीखा, जो स्ट्रिंग मामलों के साथ करने के लिए सुपर है :)
LinconFive

एक स्विच / मामले की तुलना में क्या एक सुंदर समाधान, अच्छा पठनीय और बहुत अधिक कार्यक्षमता - धन्यवाद! ब्रैकेट बंद करने के बाद "switchs_end:" मत भूलना।
अचिम

6

स्ट्रिंग खोज को तेज़ी से करने का एक तरीका है। मान्यताओं: चूंकि हम एक स्विच स्टेटमेंट के बारे में बात कर रहे हैं, मैं मान सकता हूं कि रनटाइम के दौरान मान नहीं बदल रहे हैं।

विचार सी stdlib के qsort और bsearch का उपयोग करना है।

मैं xtofl के कोड पर काम करूंगा।

struct stringcase { char* string; void (*func)(void); };

void funcB1();
void funcAzA();

struct stringcase cases [] = 
{ { "B1", funcB1 }
, { "AzA", funcAzA }
};

struct stringcase work_cases* = NULL;
int work_cases_cnt = 0;

// prepare the data for searching
void prepare() {
  // allocate the work_cases and copy cases values from it to work_cases
  qsort( cases, i, sizeof( struct stringcase ), stringcase_cmp );
}

// comparator function
int stringcase_cmp( const void *p1, const void *p2 )
{
  return strcasecmp( ((struct stringcase*)p1)->string, ((struct stringcase*)p2)->string);
}

// perform the switching
void myswitch( char* token ) {
  struct stringcase val;
  val.string=token;
  void* strptr = bsearch( &val, work_cases, work_cases_cnt, sizeof( struct stringcase), stringcase_cmp );
  if (strptr) {
    struct stringcase* foundVal = (struct stringcase*)strptr;
    (*foundVal->func)();
    return OK;
  }
  return NOT_FOUND;
}

6

ऊपर Phimueme के उत्तर में जोड़ने के लिए, यदि आपका तार हमेशा दो वर्णों का है, तो आप दो 8-बिट वर्णों में से 16-बिट int बना सकते हैं - और उस पर स्विच (नेस्टेड स्विच / केस स्टेटमेंट से बचने के लिए)।


यदि आप वास्तव में चाहते हैं To add to Phimueme's answer above, तो टिप्पणी समारोह का उपयोग करने के लिए स्वतंत्र महसूस करें। :)
प्याज-नाइट

3
@ ऑनियन: आप ध्यान देंगे कि माइकब्रोम के पास वर्तमान में अपने स्वयं के अलावा अन्य पदों पर टिप्पणी करने और अपने स्वयं के सवालों के जवाब देने की प्रतिष्ठा नहीं है। उस ने कहा, @Mike "ऊपर" SO में फिसलन है, क्योंकि वहाँ कोई विश्वसनीय क्रम नहीं है। की तरह जवाब के लिए लिंक करने के लिए बेहतर "... Phimueme के जवाब में ..." (हालांकि कि इस सवाल का जवाब अब हटा दिया गया है, और लिंक 10k + प्रतिष्ठा के साथ उपयोगकर्ता के लिए केवल अच्छा है)।
dmckee --- पूर्व-मध्यस्थ बिल्ली का बच्चा

3

हम दूसरों के साथ एक स्ट्रिंग की तुलना करने के लिए अगर-और सीढ़ी से बच नहीं सकते। यहां तक ​​कि नियमित स्विच-केस भी आंतरिक रूप से (यदि पूर्णांकों के लिए) सीढ़ी है। हम केवल स्ट्रिंग के लिए स्विच-केस का अनुकरण करना चाहते हैं, लेकिन कभी-भी सीढ़ी की जगह नहीं ले सकते। स्ट्रिंग तुलना के लिए एल्गोरिदम का सबसे अच्छा strcmp फ़ंक्शन का उपयोग करने से बच नहीं सकता है। चरित्र की तुलना चरित्र द्वारा किया जाता है जब तक कि एक बेजोड़ नहीं पाया जाता है। तो अगर-और सीढ़ी और स्ट्रैम्प का उपयोग करना अपरिहार्य है।

डेमो

और यहां स्ट्रिंग्स के लिए स्विच-केस का अनुकरण करने के लिए सबसे सरल मैक्रो हैं।

#ifndef SWITCH_CASE_INIT
#define SWITCH_CASE_INIT
    #define SWITCH(X)   for (char* __switch_p__ = X, int __switch_next__=1 ; __switch_p__ ; __switch_p__=0, __switch_next__=1) { {
    #define CASE(X)         } if (!__switch_next__ || !(__switch_next__ = strcmp(__switch_p__, X))) {
    #define DEFAULT         } {
    #define END         }}
#endif

और आप उनका उपयोग कर सकते हैं

char* str = "def";

SWITCH (str)
    CASE ("abc")
        printf ("in abc\n");
        break;
    CASE ("def")              // Notice: 'break;' statement missing so the control rolls through subsequent CASE's until DEFAULT 
        printf("in def\n");
    CASE ("ghi")
        printf ("in ghi\n");
    DEFAULT
        printf("in DEFAULT\n");
END

आउटपुट:

in def
in ghi
in DEFAULT

नीचे घोंसले के शिकार का उपयोग किया जाता है:

char* str = "def";
char* str1 = "xyz";

SWITCH (str)
    CASE ("abc")
        printf ("in abc\n");
        break;
    CASE ("def")                                
        printf("in def\n");
        SWITCH (str1)                           // <== Notice: Nested SWITCH
            CASE ("uvw")
                printf("in def => uvw\n");
                break;
            CASE ("xyz")
                printf("in def => xyz\n");
                break;
            DEFAULT
                printf("in def => DEFAULT\n");
        END
    CASE ("ghi")
        printf ("in ghi\n");
    DEFAULT
        printf("in DEFAULT\n");
END

आउटपुट:

in def
in def => xyz
in ghi
in DEFAULT

यहाँ रिवर्स स्ट्रिंग SWITCH है, जहाँ आप CAS (खंड) में एक चर (स्थिर के बजाय) का उपयोग कर सकते हैं:

char* str2 = "def";
char* str3 = "ghi";

SWITCH ("ghi")                      // <== Notice: Use of variables and reverse string SWITCH.
    CASE (str1)
        printf ("in str1\n");
        break;
    CASE (str2)                     
        printf ("in str2\n");
        break;
    CASE (str3)                     
        printf ("in str3\n");
        break;
    DEFAULT
        printf("in DEFAULT\n");
END

आउटपुट:

in str3

"यहां तक ​​कि नियमित स्विच-केस आंतरिक रूप से (पूर्णांकों के लिए) सीढ़ी भी है" यह सच नहीं है। यदि संभव हो, तो कंपाइलर एक जंप टेबल उत्पन्न करेगा, जो बहुत अधिक कुशल होगा। Stackoverflow.com/a/14067661/4990392
दादा

2

यह आमतौर पर मैं इसे कैसे करता हूं।

void order_plane(const char *p)
{
    switch ((*p) * 256 + *(p+1))
    {
        case 0x4231 : /* B1 */
        {
           printf("Yes, order this bomber.  It's a blast.\n");
           break;
        }

        case 0x5354 : /* ST */
        {
            printf("Nah.  I just can't see this one.\n");
            break;
        }

        default :
        {
            printf("Not today.  Can I interest you in a crate of SAMs?\n";
        }
    }
}

दिलचस्प। Lacks (शायद पसंद से) रक्षात्मक कोडिंग। और मैं मामले में अतिरिक्त ब्रेसिज़ की प्रशंसा करता हूं। कोड को इतना अधिक पठनीय बनाता है (हालांकि मैं मामले के लिए मिस्र के ब्रेसिज़ पसंद करता हूं)।
डेरियस

1
BTW, आप केस लेबल में निरंतर भाव का उपयोग कर सकते हैं। case 'B'<<8+'1':मुझे लगता है कि यह 0x4231 से अधिक स्पष्ट होगा।
जेन्स

मैं एक मैक्रो का उपयोग करेगा। #define twochar(a) (((uint16_t)a[1]<<8)|a[0])
v7d8dpo4

1

इसे आपको इसी तरह करना होगा। नहीं वास्तव में नहीं।

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>


 #define p_ntohl(u) ({const uint32_t Q=0xFF000000;       \
                     uint32_t S=(uint32_t)(u);           \
                   (*(uint8_t*)&Q)?S:                    \
                   ( (S<<24)|                            \
                     ((S<<8)&0x00FF0000)|                \
                     ((S>>8)&0x0000FF00)|                \
                     ((S>>24)&0xFF) );  })

main (void)
{
    uint32_t s[0x40]; 
    assert((unsigned char)1 == (unsigned char)(257));
    memset(s, 0, sizeof(s));
    fgets((char*)s, sizeof(s), stdin);

    switch (p_ntohl(s[0])) {
        case 'open':
        case 'read':
        case 'seek':
            puts("ok");
            break;
        case 'rm\n\0':
            puts("not authorized");
            break;
        default:
            puts("unrecognized command");  
    }
    return 0;
}

3
मुझे नहीं लगता कि यह मानक सी है
जोहान कोटलिंस्की

2
मैक्रो सपोर्ट को मिश्रित धीरज बनाना, या एक फ़ंक्शन को पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है।

2
यह मानक C है, लेकिन पोर्टेबल नहीं है। मल्टी-बाइट चार का बाइट ऑर्डर 'कार्यान्वयन निर्भर' है और मशीनों को बाइट ऑर्डर को प्रतिबिंबित करने की आवश्यकता नहीं है। मैंने इसका इस्तेमाल एक बार किया और जल गया: सोलारिस स्पार्क (बड़ा एंडियन) GNU-C 3.4 पर Sunstudio 12. की तुलना में एक अलग बाइट ऑर्डर का उपयोग किया गया
पैट्रिक

@tristopia आप निश्चित रूप से सही हैं (असली के लिए ऐसा कुछ करने का प्रयास करने के बाद ही सही हो सकता है)। यही कारण है कि हम सभी को इसके बजाय बी का उपयोग करना चाहिए।

आपने अपना खाता क्यों मारा?

1

यदि यह एक 2 बाइट स्ट्रिंग है तो आप इस ठोस उदाहरण में कुछ कर सकते हैं जहां मैं ISO639-2 भाषा कोड पर स्विच करता हूं।

    LANIDX_TYPE LanCodeToIdx(const char* Lan)
    {
      if(Lan)
        switch(Lan[0]) {
          case 'A':   switch(Lan[1]) {
                        case 'N': return LANIDX_AN;
                        case 'R': return LANIDX_AR;
                      }
                      break;
          case 'B':   switch(Lan[1]) {
                        case 'E': return LANIDX_BE;
                        case 'G': return LANIDX_BG;
                        case 'N': return LANIDX_BN;
                        case 'R': return LANIDX_BR;
                        case 'S': return LANIDX_BS;
                      }
                      break;
          case 'C':   switch(Lan[1]) {
                        case 'A': return LANIDX_CA;
                        case 'C': return LANIDX_CO;
                        case 'S': return LANIDX_CS;
                        case 'Y': return LANIDX_CY;
                      }
                      break;
          case 'D':   switch(Lan[1]) {
                        case 'A': return LANIDX_DA;
                        case 'E': return LANIDX_DE;
                      }
                      break;
          case 'E':   switch(Lan[1]) {
                        case 'L': return LANIDX_EL;
                        case 'N': return LANIDX_EN;
                        case 'O': return LANIDX_EO;
                        case 'S': return LANIDX_ES;
                        case 'T': return LANIDX_ET;
                        case 'U': return LANIDX_EU;
                      }
                      break;
          case 'F':   switch(Lan[1]) {
                        case 'A': return LANIDX_FA;
                        case 'I': return LANIDX_FI;
                        case 'O': return LANIDX_FO;
                        case 'R': return LANIDX_FR;
                        case 'Y': return LANIDX_FY;
                      }
                      break;
          case 'G':   switch(Lan[1]) {
                        case 'A': return LANIDX_GA;
                        case 'D': return LANIDX_GD;
                        case 'L': return LANIDX_GL;
                        case 'V': return LANIDX_GV;
                      }
                      break;
          case 'H':   switch(Lan[1]) {
                        case 'E': return LANIDX_HE;
                        case 'I': return LANIDX_HI;
                        case 'R': return LANIDX_HR;
                        case 'U': return LANIDX_HU;
                      }
                      break;
          case 'I':   switch(Lan[1]) {
                        case 'S': return LANIDX_IS;
                        case 'T': return LANIDX_IT;
                      }
                      break;
          case 'J':   switch(Lan[1]) {
                        case 'A': return LANIDX_JA;
                      }
                      break;
          case 'K':   switch(Lan[1]) {
                        case 'O': return LANIDX_KO;
                      }
                      break;
          case 'L':   switch(Lan[1]) {
                        case 'A': return LANIDX_LA;
                        case 'B': return LANIDX_LB;
                        case 'I': return LANIDX_LI;
                        case 'T': return LANIDX_LT;
                        case 'V': return LANIDX_LV;
                      }
                      break;
          case 'M':   switch(Lan[1]) {
                        case 'K': return LANIDX_MK;
                        case 'T': return LANIDX_MT;
                      }
                      break;
          case 'N':   switch(Lan[1]) {
                        case 'L': return LANIDX_NL;
                        case 'O': return LANIDX_NO;
                      }
                      break;
          case 'O':   switch(Lan[1]) {
                        case 'C': return LANIDX_OC;
                      }
                      break;
          case 'P':   switch(Lan[1]) {
                        case 'L': return LANIDX_PL;
                        case 'T': return LANIDX_PT;
                      }
                      break;
          case 'R':   switch(Lan[1]) {
                        case 'M': return LANIDX_RM;
                        case 'O': return LANIDX_RO;
                        case 'U': return LANIDX_RU;
                      }
                      break;
          case 'S':   switch(Lan[1]) {
                        case 'C': return LANIDX_SC;
                        case 'K': return LANIDX_SK;
                        case 'L': return LANIDX_SL;
                        case 'Q': return LANIDX_SQ;
                        case 'R': return LANIDX_SR;
                        case 'V': return LANIDX_SV;
                        case 'W': return LANIDX_SW;
                      }
                      break;
          case 'T':   switch(Lan[1]) {
                        case 'R': return LANIDX_TR;
                      }
                      break;
          case 'U':   switch(Lan[1]) {
                        case 'K': return LANIDX_UK;
                        case 'N': return LANIDX_UN;
                      }
                      break;
          case 'W':   switch(Lan[1]) {
                        case 'A': return LANIDX_WA;
                      }
                      break;
          case 'Z':   switch(Lan[1]) {
                        case 'H': return LANIDX_ZH;
                      }
                      break;
        }
      return LANIDX_UNDEFINED;
    }

LANIDX_ * सरणियों में अनुक्रमित करने के लिए निरंतर पूर्णांकों का उपयोग किया जा रहा है।


0

थोड़ा धीरज और आकार (चार) == 1 मानते हुए, आप ऐसा कर सकते हैं (कुछ ऐसा ही माइकब्रोम द्वारा सुझाया गया था)।

char* txt = "B1";
int tst = *(int*)txt;
if ((tst & 0x00FFFFFF) == '1B')
    printf("B1!\n");

इसे बीई केस के लिए सामान्यीकृत किया जा सकता है।


2
ऐसा मत करो! इसके कारण "डेटा संरेखण" अपवाद हो सकता है। यह गारंटी नहीं है कि char * txt एक पते पर इंगित करता है, जो इंट की संरेखण आवश्यकताओं से मेल खाता है।
हार्पर

@ आर उसने उसके लिए कहा। @ यह x86 के लिए मामला नहीं है।
रसिक २५'१०

निकल्स ने x86 नहीं मांगा। और जब से आपने बड़े एंडियन मामले का उल्लेख किया है, आप विशेष रूप से x86 वातावरण को संबोधित नहीं करते हैं। इतना कि '
हार्पर

इसके अलावा, मशीन बाइट क्रम में बहु-बाइट वर्ण आवश्यक नहीं हैं। Jbcreix उत्तर के लिए मेरी टिप्पणी देखें।
पैट्रिक श्ल्टर

0

फंक्शन पॉइंटर्स ऐसा करने का एक शानदार तरीका है, जैसे

result = switchFunction(someStringKey); //result is an optional return value

... यह एक फ़ंक्शन को कहता है जिसे आपने स्ट्रिंग कुंजी द्वारा सेट किया है (प्रति मामले एक फ़ंक्शन):

setSwitchFunction("foo", fooFunc);
setSwitchFunction("bar", barFunc);

पहले से मौजूद हैशमैप / टेबल / डिक्शनरी क्रियान्वयन जैसे कि खश का उपयोग करें, उस पॉइंटर को किसी फंक्शन के अंदर लौटाएँ switchFunction(), और उसे निष्पादित करें (या बस इसे वापस लौटाएँ switchFunction()और इसे स्वयं निष्पादित करें)। यदि मानचित्र कार्यान्वयन स्टोर नहीं करता है, तो बस uint64_tइसके बजाय एक पॉइंटर के अनुसार कास्ट करें।


@ eri0o यदि आपको लगता है कि यह सभ्य था, तो इसे अपवित्र क्यों नहीं किया गया? मूल downvoter लंबे समय से चला गया है।
इंजीनियर

-2

यदि आपके पास यह मामला है तो यह आसान और तेज़ तरीका है:

[त्वरित मोड]

int concated;
char ABC[4]="";int a=1,b=4,c=2;            //char[] Initializing
ABC<-sprintf(ABC,"%d%d%d",a,b,c);          //without space between %d%d%d
printf("%s",ABC);                          //value as char[] is =142
concated=atoi(ABC);                        //result is 142 as int, not 1,4,2 (separeted)

//now use switch case on 142 as an integer and all possible cases

[विस्तारित मोड]

उदाहरण के लिए: मेरे पास कई मेनू हैं, 1 मेनू पर प्रत्येक विकल्प को 2 मेनू पर ले जाता है, 2 मेनू और 3 मेनू के साथ एक ही बात होती है। लेकिन विकल्प अलग-अलग होते हैं, ताकि आप जान सकें कि उपयोगकर्ता ने वित्तीय स्थिति का चयन किया है। छूट:

मेनू 1: 1 ==> मेनू 2: 4 ==> मेनू 3: 2 (...) पसंद 142 है। अन्य मामले: 111,141,131,122 ...

sollution: पहले 1st को a, 2nd को b, 3rd को c पर store करें। a = 1, b = 4, c = 2

 char ABC[4]="";
 ABC<-sprintf(ABC,"%d%d%d",a,b,c);              //without space between %d%d%d
 printf("%s",ABC);                              //value as char[]=142

      //now you want to recover your value(142) from char[] to int as  int value 142

 concated=atoi(ABC);                            //result is 142 as int, not 1,4,2 (separeted)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.