'switch'문을 사용하여 C의 문자열을 어떻게 비교할 수 있습니까?


84

C에는 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

질문이 당신이 실제로하려는 (또는 요구하는) 것을 명확히 할 수 있도록 재구성하십시오.
Šimon Tóth

8
OP는 아마도 switch 문의 매개 변수로 문자열을 사용하려고 할 것입니다. 내가 아는 한 이것은 불가능합니다.
dandan78

답변:


101

의미하는 경우 다음과 유사한 내용을 작성하는 방법 :

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

그런 다음 C의 표준 솔루션은 if-else 래더를 사용하는 것입니다.

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

1
실제로 문제는 이미 int에 스위치가 있고 특별한 경우에는 동일한 스위치에서 사용하려는 "B1"과 "B2"값이 있다는 것입니다. 유일한 방법은 "B1"및 "B2"값을 어떻게 든 변환하여 int !!?
Niklas

2
@Niklas : 이것은 귀하의 질문에 대한 중요한 정보입니다. 질문을 업데이트하고 (가능한 경우 일부 (의사) 코드로) 수행하려는 작업을 설명 할 수 있습니까?
Bart van Ingen Schenau

4
@Niklas : 질문을 명확히해야합니다. 어떻게 "B1"과 "B2"가 int의 특별한 경우가 될 수 있습니까?
Edgar Bonet

1
#define A 1 #define B 2 #define C S1 #define D S2 및 이러한 값은 스위치에서 사용하고 싶은 것입니다. 너무 간단합니다 :-)
Niklas

5
@Niklas : 정의는 문자열이 아닙니다. 정의가 숫자에 대한 것이라면 다음과 같이 스위치에서 직접 사용할 수 있습니다 switch (something) { case A: /*...*/ break; case B: /*...*/ break; }.
Bart van Ingen Schenau

45

케이스가 많고 많은 strcmp()통화 를 작성하고 싶지 않은 경우 다음과 같이 할 수 있습니다.

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

해시 함수가 문자열의 가능한 값 집합 내에 충돌이 없는지 확인하기 만하면됩니다.


8
"해시 함수가 문자열에 대해 가능한 값 세트 내에 충돌이 없는지 확인하십시오." -알파벳에 대해 그러한 해시 함수가 존재 [a-zA-Z0-9_]합니까? 어떤 예?
Arun

8
@ArunSaha : 분명히 그러한 문자의 임의 조합 이 아닙니다 .
Edgar Bonet

3
고정 길이 문자열 키를 사용하는 경우 각각 고유 한 정수로 변환 할 수 있습니다. 충돌이 없습니다.
엔지니어

@ArcaneEngineer 음 ... 그게 문제가 해결하려는 정확한 문제가 아닙니까? 문자열 만 주어지면 함께 사용할 정수를 어떻게 고르겠습니까? "스위치 또는 if / else 래더 사용"아니면 4 자처럼 매우 짧은 것을 의미합니까?
ebyrob

@ebyrob 나는 uint비트가 8 개의 1 바이트 ASCII로 처리되는 2 개의 64 비트와 같이 빠른 작업에서 비교할 수있는 모든 것을 의미했습니다 char. C의 해시 테이블 내에서 키 비교를 위해 이것을 얼마 전에 구현했습니다. 따라서 해싱이나 버킷이 필요하지 않습니다. 문제는 64 비트를 초과해야하는 경우에 발생합니다. 그런 다음 char전체 문자열에서 8 초의 각 세트를 반복 할 때 조건에 대한 비용을 지불 합니다. 루프를 펼치지 않는 한 키의 최대 크기를 알고 있다면. 그것은 좋은 균형을 잡는 행위입니다.
엔지니어

39

C에서는이 작업을 수행 할 수 없습니다. 다양한 접근 방식이 있습니다. 일반적으로 가장 간단한 방법은 문자열을 나타내는 상수 집합을 정의하고 상수를 얻기 위해 문자열로 검색하는 것입니다.

#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 세트 대신 열거 형을 사용하는 것이 훨씬 더 좋지만 그렇지 않으면 최선을 다할 수 있습니다.
Craig Ringer

증가가 올바르지 않습니다. lookuptable + i * sizeof (t_symstruct)가 lookuptable [i]와 같지 않습니다.
asdf

@asdf 이것이 c에서 포인터 산술이 작동하는 방식입니다. sizeof는 암시 적입니다.
ijustlovemath

20

이 작업을 수행하는 데 선호하는 방법은 해시 함수를 사용하는 것입니다 ( 여기 에서 빌림 ). 이렇게하면 char *로 작업 할 때에도 switch 문의 효율성을 활용할 수 있습니다.

#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);
    }
}

물론이 접근 방식에서는 허용되는 모든 char *에 대한 해시 값이 미리 계산되어야합니다. 나는 이것이 너무 큰 문제라고 생각하지 않습니다. 그러나 switch 문은 상관없이 고정 값에서 작동하기 때문입니다. 해시 함수를 통해 char *를 전달하고 그 결과를 출력하는 간단한 프로그램을 만들 수 있습니다. 이러한 결과는 위에서 한 것처럼 매크로를 통해 정의 할 수 있습니다.


Stack Overflow에 오신 것을 환영합니다. 당신이 보여준 것은 멋지게 제시되고 좋은 아이디어이지만… 다른 답변들과 크게 다르지는 않습니다.이 아이디어에 사소한 변형을 사용하는 몇 가지가 있습니다. 오래된 안정된 질문에 새로운 답변을 추가한다면, 좋은 새로운 정보가 있다는 것을 확신해야합니다. 그것은 대부분주의의 말입니다. 나는 이것에 대해 당신을 하향 투표하지 않을 것입니다.
Jonathan Leffler

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

나는 출판했다 C의 문자열에서 전환을 수행하기 위해 헤더 파일 을 했습니다. 여기에는 스위치와 유사한 동작을 모방하기 위해 strcmp () (또는 이와 유사한)에 대한 호출을 숨기는 매크로 집합이 포함되어 있습니다. Linux에서 GCC로만 테스트했지만 다른 환경을 지원하도록 조정할 수 있다고 확신합니다.

편집 : 요청에 따라 여기에 코드 추가

다음은 포함해야하는 헤더 파일입니다.

#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;

"휴식"을 추가하는 것이 아니라 생략 할 수 있다는 사실을 강조하여 예제를 편집했습니다
Andrea Carron

1
그게 더 좋습니다! 일치하기 위해 "sscanf"를 사용하기 전에 "regex.h"를 배웠습니다. 문자열
대소 문자

스위치 / 케이스와 비교할 때 얼마나 아름다운 솔루션이고 가독성이 좋으며 훨씬 더 많은 기능을 제공합니다. 감사합니다! 닫는 대괄호 뒤에 "switchs_end :"를 잊지 마세요.
Achim

6

문자열 검색을 더 빠르게 수행 할 수있는 방법이 있습니다. 가정 : 우리는 switch 문에 대해 이야기하고 있기 때문에 런타임 동안 값이 변경되지 않는다고 가정 할 수 있습니다.

아이디어는 C 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주석 기능을 사용하십시오. :)
Onion-Knight

3
@Onion : MikeBrom은 현재 자신의 게시물과 자신의 질문에 대한 답변 이외의 게시물에 댓글을 달 수있는 명성이 없습니다. 즉, @Mike "위"는 신뢰할 수있는 정렬 순서가 없기 때문에 미끄 럽습니다. "... Phimueme의 답변 ..." 과 같은 답변에 연결하는 것이 더 좋습니다 (해당 답변은 지금 삭제되고 링크는 평판이 10k 이상인 사용자에게만 적합합니다).
dmckee --- 전 중재자 새끼 고양이

3

문자열을 다른 문자열과 비교하기 위해 if-else 래더를 벗어날 수 없습니다. 일반 switch-case도 내부적으로 if-else 래더 (정수용)입니다. 문자열에 대한 switch-case 만 시뮬레이션하고 싶을 수도 있지만 if-else 래더를 대체 할 수는 없습니다. 문자열 비교를위한 최고의 알고리즘은 strcmp 함수 사용에서 벗어날 수 없습니다. 불일치가 발견 될 때까지 문자별로 비교하는 것을 의미합니다. 따라서 if-else 래더와 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

아래는 중첩 된 SWITCH 사용법입니다.

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입니다. 여기서 CASE 절에서 변수 (상수 대신)를 사용할 수 있습니다.

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

"일반적인 switch-case조차도 내부적으로 if-else 래더 (정수용)입니다."이는 사실이 아닙니다. 가능하다면 컴파일러는 훨씬 더 효율적인 점프 테이블을 생성합니다. 참조 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";
        }
    }
}

흥미 롭군. 방어적인 코딩이 부족합니다 (아마 선택에 따라). 그리고 나는 경우에 대비하여 추가 중괄호에 감탄합니다. 코드를 훨씬 더 읽기 쉽게 만듭니다 (대소 문자로 이집트 중괄호를 선호하지만).
Dariusz

1
BTW, 케이스 레이블에 상수 표현식을 사용할 수 있습니다. case 'B'<<8+'1':제 생각에는 0x4231보다 더 명확 해집니다.
Jens 2013 년

매크로를 사용합니다. #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
나는이 표준 C. 생각하지 않는다
요한 Kotlinski

2
매크로가 혼합 엔디안을 지원하도록하거나 기능은 독자를위한 연습으로 남겨집니다.

2
표준 C이지만 휴대용은 아닙니다. 멀티 바이트 문자의 바이트 순서는 '구현 종속성'이며 시스템 바이트 순서를 반영 할 필요가 없습니다. 나는 그것을 사용 한 번 태워있어 : 솔라리스 SPARC (빅 엔디안) 선 스튜디오 (12)에 비해 GNU-C 3.4을 사용하는 다른 바이트 순서에
패트릭 Schlüter

@tristopia 물론 당신이 맞습니다 (실제로 이와 같은 일을 시도한 후에 할 수있는 것처럼). 이것이 우리 모두가 대신 B를 사용해야하는 이유입니다.

왜 계정을 죽였습니까?

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

작은 엔디안과 sizeof (char) == 1이라고 가정하면 그렇게 할 수 있습니다 (이와 같은 것은 MikeBrom이 제안했습니다).

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

BE의 경우 일반화 할 수 있습니다.


2
하지마! 이로 인해 "데이터 정렬"예외가 발생할 수 있습니다. char * txt가 int의 정렬 요구 사항과 일치하는 주소를 가리키는 것은 보장되지 않습니다.
harper

@R 그는 그것을 요구했습니다. @harper x86의 경우가 아닙니다.
ruslik

Niklas는 x86을 요구하지 않았습니다. 그리고 빅 엔디안 사례를 언급 했으므로 x86 환경 만 다루지는 않습니다. 그래서 '
하퍼

또한, 멀티 바이트 문자는 반드시 머신 바이트 순서가 아닙니다. jbcreix 답변에 대한 내 의견을 참조하십시오.
Patrick Schlüter

0

함수 포인터는이를 수행하는 좋은 방법입니다.

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

... 문자열 키로 설정 한 함수를 호출합니다 (케이스 당 하나의 함수).

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

khash와 같은 기존 해시 맵 / 테이블 / 사전 구현을 사용하고 해당 포인터를의 내부 함수에 반환 switchFunction()하고 실행합니다 (또는 그냥 반환 switchFunction()하고 직접 실행). 지도 구현이 그것을 저장하지 않으면 uint64_t대신 포인터에 따라 캐스팅 하는 대신 사용하십시오 .


@ eri0o 괜찮다고 생각했다면 왜 찬성하지 않습니까? 원래의 반대 투표자는 오래 전부터 사라졌습니다.
엔지니어

-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

[EXPLAINED 모드]

예를 들어 : 나는 많은 메뉴를 가지고 있으며, 첫 번째 메뉴의 각 선택은 두 번째 메뉴로 이동하고 두 번째 메뉴와 세 번째 메뉴와 동일하지만 옵션이 다르므로 사용자가 끝까지 선택했음을 알 수 있습니다. 예 :

메뉴 1 : 1 ==> 메뉴 2 : 4 ==> 메뉴 3 : 2 (...) 선택은 142. 기타 경우 : 111,141,131,122 ...

해결책 : 첫 번째는 a에, 두 번째는 b에, 세 번째는 c에 저장합니다. 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.