【问题标题】:How to get the value of enum from a string如何从字符串中获取枚举的值
【发布时间】:2021-04-04 09:25:29
【问题描述】:

code is here!

我试图从用户输入中将枚举值的值作为字符串获取,并希望解码该值并根据它打印大小写,使用 Switch case 但无法解码确切的值。

enum design {E2F = 1, E2, E3, E4, E5};    char *designation[5];

如果有人帮助我会很高兴

谢谢。

【问题讨论】:

  • 您必须使用 atoi 或任何等效功能将字符串转换为数字。
  • 请显示问题中的代码——在接下来的一两年内,指向外部网站的链接不够可靠。
  • 为什么不使用char *designation[] = { "E2F", "E2", "E3", "E4", "E5" };,然后使用indexstrcmp()if (strcmp(designation[index], input) == 0) switch (index) { ... } 输入并循环designation
  • 您是否要求用户能够输入'E4'并且代码可以将该字符串映射到4,即enum design中的对应值?
  • 是的,@JonathanLeffler 我正在寻找那个

标签: c string enums c-strings


【解决方案1】:

C 枚举值只是命名整数。对于字符串转换,您需要自己动手(例如,与 Java 不同,枚举更强大)。将字符串转换为枚举的一种方法是使用库 bsearch 函数:

#include <stdlib.h>
#include <assert.h>
#include <string.h>

enum design {E2F = 1, E2, E3, E4, E5};

struct design_value {
  const char *design;
  enum design value;
} designs[] = {
  {"E2", E2},
  {"E2F", E2F},
  {"E3", E3},
  {"E4", E4},
  {"E5", E5},
};

static int design_value_cmp(const void *a, const void *b) {
  return strcmp(((struct design_value*) a)->design, ((struct design_value*) b)->design);
}

enum design get_design(char *designation) {
  struct design_value key[1] = {{ designation }};
  struct design_value *result = (struct design_value*) bsearch(
    key, 
    designs, sizeof designs / sizeof designs[0], sizeof designs[0], 
    design_value_cmp);
  assert(result);
  return result->value;
}

// Tiny verifier. Don't use scanf("%s"...) in real code.
#include <stdio.h>

int main(void) {
  char buf[100];
  scanf("%s", buf);
  printf("%d\n", get_design(buf));
  return 0;
}

注意bsearch 要求字符串按字母顺序排列。

【讨论】:

  • bsearch 似乎有点过头了。为什么不直接使用 for 循环来查找呢?
  • bsearch 意味着一个排序数组,而您已经手动完成了。允许用户按自然顺序指定数据然后让程序对其进行排序可能会更好。这也消除了程序员错误排序的数据。 bsearch 是 O(log n) 但通常在 n > 1000 左右之前不会更快(取决于硬件,但 n 在实践中非常大)。我认为有另一个解决方案很棒。
  • @AllanWind - 我同意 - bsearch 对于少量项目可能会更慢
  • stackoverflow.com/questions/1621394/… 有一些建议在 scanf 中重新溢出。
  • 即使用 scanf("%100s, ...), fgets 或读取
【解决方案2】:

枚举将符号映射到数字。以下是我们讨论的 3 个选项:

  1. 如果要将字符串映射到数字,请使用结构:

    struct {
      const char *design;
      int value;
    } designs[] = {
      {"E2F", 1},
      {"E2", 2},
      {"E3", 3}
      {"E4", 4},
      {"E5", 5}
    };
    
  2. 如果你想根据枚举定义结构。从相同的数据(设计)生成两者:

     #define DESIGNS\
     _(E2F, 1)\
     _(E2, 2)\
     _(E3, 3)\
     _(E4, 4)\
     _(E5, 5)
    
     #define _(A, B) A = B,
     enum {
       DESIGNS
     };
    
     #undef _
     #define _(A, B) { #A, A },
     struct {
       const char *design;
       int value;
     } designs[] = {
       DESIGNS
     };
    

预处理器将扩展为:

    enum {
      E2F = 1, E2 = 2, E3 = 3, E4 = 4, E5 = 5,
    };

    struct {
      const char *design;
      int value;
    } designs[] = {
      { "E2F", E2F }, { "E2", E2 }, { "E3", E3 }, { "E4", E4 }, { "E5", E5 },
    };
  1. 这是@DavidCRankin 的建议(如果我理解正确的话)只存储数组以从索引中获取值:

     #include <string.h>
    
     int design_to_number(const char *str) {
       const char *designs[] = { "E2F", "E2", "E3", "E4", "E5" };
       for(int i = 0; i < sizeof(designs) / sizeof(*designs); i++) {
         if(!strcmp(designs[i], str)) return i + 1;
       }
       return -1;
     }
    

【讨论】:

  • 这意味着你需要同步结构和枚举。不过,您可以从相同的数据生成两者。
  • X-macro 方法没有提供检查列表末尾(或哨兵)的方法,OP 想从字符串中搜索,你怎么知道何时停止扫描/搜索?我会使用类似ideone.com/PvhmPv
  • sizeof(array)/sizeof(*array) 为您提供数组的大小,因此您不需要哨兵。
  • @AllanWind 是的,是一个选项,好点!
猜你喜欢
  • 1970-01-01
  • 2022-11-10
  • 2010-10-10
  • 2010-12-07
  • 2017-07-03
  • 2013-07-18
  • 1970-01-01
  • 2020-07-11
相关资源
最近更新 更多