如何在C中维护字符串与其索引之间的映射?

时间:2014-05-26 04:26:04

标签: c

我有一个枚举 例如

enum {
APPLE,
MANGO,
BANANA
}

和相应的字符串数组

char fruits[] = 
{
 "apple",
 "mango",
 "banana"
}

我需要检索字符串的索引,因为我有字符串。因此,如果字符串是苹果,我需要得到0,依此类推。另外还有{Enum,可能有助于解决方案]

是否有一种优雅的方式来保存简短的[apple,0],[banana,1],我可以将其用作宏。我不需要像散列表那样冗长的东西。 Enum可以协助映射吗?

4 个答案:

答案 0 :(得分:10)

您可以执行类似

的操作

entries.h

 ENTRY(APPLE, "apple"), 
 ENTRY(MANGO, "mango"),

在您的档案中

#define ENTRY(a,b) b
const char *fruits [] = {
#include "entries.h"
} ; 

#undef ENTRY
#define ENTRY(a,b) a
enum fruit_t
{
#include "entries.h"
} ;

答案 1 :(得分:4)

你无法真正做到"映射"用C中的字符串。

最直接的解决方案是简单的线性搜索:

typedef enum {
  INVALID = -1,

  APPLE = 0,
  MANGO,
  BANANA,

  NUM_FRUIT,
} fruit_t;

// NOTE: These indices must be kept in-sync with fruit_t!
const char* fruits[] = {
 "apple",
 "mango",
 "banana"
};

fruit_t lookup_fruit(const char* name) {
    int i;
    for (i=0; i<NUM_FRUIT; i++) {
        if (strcmp(name, fruits[i]) == 0)
            return i;
    }
    return INVALID;
}

void test(void) {
    fruit_t result = lookup_fruit("mango");
}

答案 2 :(得分:2)

在C99或C11中,您可以使用指定的初始值设定项:

enum { APPLE, MANGO, BANANA = 7 };

char *fruits[] = 
{
    [BANANA] = "banana",
    [MANGO]  = "mango",
    [APPLE]  = "apple",
};

即使项目没有以相同的顺序列出,即使MANGO和BANANA之间存在很大差距,这也能正常工作。

答案 3 :(得分:0)

这是user3344003解决方案的另一种布局,不需要每个.c文件来提供家具;并包括警卫:

// entries.h
#ifndef H_ENTRIES
    // other stuff for this header file that needs to be in header guards
#endif

// make sure to only include the enum once even if the file is multiply included
#if (!defined H_ENTRIES) || (defined C_ENTRIES)

#ifndef C_ENTRIES
    enum 
    {
#   define ENTRY(a,b) a
#endif

    ENTRY(APPLE, "apple"), 
    ENTRY(MANGO, "mango"),

#ifndef C_ENTRIES
    NUM_FRUITS
    };
    extern const char *fruits[NUM_FRUITS];   // if you also want array extern of course
#   undef ENTRY
#   define H_ENTRIES
#endif

// entries.c

#define C_ENTRIES
#define ENTRY(a,b) b

    const char *fruits[NUM_FRUITS] = {
#       include "entries.h"
    };

// other.c 

#include "entries.h"