【问题标题】:(C) Am I properly converting enum type to string?(C) 我是否正确地将枚举类型转换为字符串?
【发布时间】:2021-07-04 22:42:09
【问题描述】:

我对编码非常陌生,并且正在学习在线课程,但帮助很少。我正在完成一项任务,创建一堆将在以后使用的函数。在这一点上,我还没有学到任何关于点、数组或递归的知识。我对字符串的了解几乎仅限于“printf”函数。

话虽如此,我已经得到了关于函数“ranking_to_string”应该如何操作的描述:

这个函数应该转换 hand_ranking_t 枚举值传递 到一个描述它的字符串中。

这里的枚举类型是hand_ranking_t,它按照从STRAIGHT_FLUSH (0) 到NOTHING (8) 的数值降序排列一手牌。说了这么多,这是我创建的功能,以尝试遵循我的指示:

const char * ranking_to_string(hand_ranking_t r) {
  switch (r) {
  case STRAIGHT_FLUSH: printf("STRAIGHT_FLUSH\n"); break;
  case FOUR_OF_A_KIND: printf("FOUR_OF_A_KIND\n"); break;
  case FULL_HOUSE: printf("FULL_HOUSE\n"); break;
  case FLUSH: printf("FLUSH\n"); break;
  case STRAIGHT: printf("STRAIGHT\n"); break;
  case THREE_OF_A_KIND: printf("THREE_OF_A_KIND\n"); break;
  case TWO_PAIR: printf("TWO_PAIR\n"); break;
  case PAIR: printf("PAIR\n"); break;
  case NOTHING: printf("NOTHING\n"); break;
  default: printf("Invalid thing\n"); break;
  }
  return EXIT_SUCCESS;
}

我想知道,我在函数末尾返回 EXIT_SUCCESS (0) 是否正确?有没有另一种方法可以使用 printf 将输入的枚举值转换为字符串?

【问题讨论】:

  • EXIT_SUCCESS 是一些数字常量。您的函数虽然返回 char *...
  • 从这个函数返回任何东西是没有意义的,你应该把它设为void 类型。如果您确实需要返回EXIT_SUCCESS,则应将其设为int

标签: c enums return


【解决方案1】:

EXIT_SUCCESS 是一个,它将扩展为从main(或通过exit 等)返回的环境定义指标,以表明您的整个程序已成功完成它应该做什么。它通常不在此上下文之外使用。

printf 用于将输出 发送到与stdout 关联的流。例如,您可以调用 printf 在终端中显示文本。

您的函数应该改为return string literals,供ranking_to_string 的调用者使用。

const char *ranking_to_string(hand_ranking_t r) {
    switch (r) {
        case STRAIGHT_FLUSH: return "STRAIGHT_FLUSH";
        case FOUR_OF_A_KIND: return "FOUR_OF_A_KIND";
        /* ... and so on ... */
        default: return "Invalid thing";
    }
}

一个示例程序:

#include <stdio.h>

typedef enum {
    STRAIGHT_FLUSH,
    FOUR_OF_A_KIND,
    /* ... and so on ... */
} hand_ranking_t;

const char *ranking_to_string(hand_ranking_t r) {
    switch (r) {
        case STRAIGHT_FLUSH: return "STRAIGHT_FLUSH";
        case FOUR_OF_A_KIND: return "FOUR_OF_A_KIND";
        /* ... and so on ... */
        default: return "Invalid thing";
    }
}

int main(void) {
    hand_ranking_t rank = FOUR_OF_A_KIND;
    const char *rank_string = ranking_to_string(rank);

    printf("My ranking is <%s>\n", rank_string);
}

输出:

My ranking is <FOUR_OF_A_KIND>

【讨论】:

  • 我明白了,这很有意义!似乎我不明白什么是 C 中的字符串。为了我自己的缘故澄清一下,将引号添加到字符的 string 是构成字符串的原因,当我使用函数 printf 时,所有我正在做的是向用户输出一个字符串?
  • @Quinn 我已经用大量指向相应文档的链接更新了答案。但是是的,是的。例如,"Hello world" 是一个字符串文字,它实际上是一个指向包含该数据的只读内存块的指针。这就是为什么你的函数的返回类型是const char *printf 只是一个函数,它以 const char * 作为其第一个参数,并使用它来将数据发送到流(这可能是终端输出,或者可能是不同的文件)。
  • @Quinn 如果您的学习资源没有很好地解释这一点,那么我建议您再找一个。这些是相当基本的概念,通常应该按照复杂度递增的顺序来教授(即,核心语法和基本类型通常应该在函数调用之前解释)。考虑扫描The Definitive C Book Guide and List 以获得更好的学习资源。
【解决方案2】:

您的课程可能未涵盖,但可以使用 X-Macros 完全自动化 ranking_to_string。此外,由于扑克牌具有价值,因此按其列出它们是有意义的。

#include <stdlib.h>
#include <stdio.h>

#define HANDS X(HIGH_CARD), X(PAIR), X(TWO_PAIR), X(THREE_OF_A_KIND), \
    X(STRAIGHT), X(FLUSH), X(FULL_HOUSE), X(FOUR_OF_A_KIND), \
    X(STRAIGHT_FLUSH), X(ROYAL_FLUSH)

#define X(name) name
enum hand { HANDS };
#undef X
#define X(name) #name
static const char *hand_str[] = { HANDS };
#undef X
static const size_t hand_size = sizeof hand_str / sizeof *hand_str;

int main(void) {
    enum hand i, j;
    for(i = 0; i < hand_size; i++) printf("%s\n", hand_str[i]);
    i = FULL_HOUSE;
    j = FLUSH;
    printf("%s is %s than %s.\n",
        hand_str[i], i < j ? "less" : "greater", hand_str[j]);
    return EXIT_SUCCESS;
}

其中# 是预处理器的stringizing 运算符。

【讨论】:

  • 通常,您希望逗号成为 X 宏的一部分,而不是宏列表的一部分。如果您希望将宏列表用于枚举或初始化列表之外的其他内容。
  • 好点。在C99 中,可选的尾随逗号被添加到初始化列表语法中,这样更加通用。
猜你喜欢
  • 2013-01-23
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多