如何自动将常量字符串的第一个字符作为常量字符?

时间:2016-07-27 13:44:12

标签: c gcc constants

是否可以重写以下内容,因此如果字符串发生变化,我只需要在一个地方进行更改?

#define MY_STRING "Foo bar"
#define MY_STRING_FIRST_CHAR 'F'

以下是不可接受的,因为它引用了内存位置中的char,因此它不能用作switch语句中的大小写:

#define MY_STRING_FIRST_CHAR MY_STRING[0]

switch (something) {
    case MY_STRING_FIRST_CHAR:
        break;
}

目的是通过查看一个字符来有效地解析收到的字符串。在我的例子中,所有字符串都有一个唯一字符以下不是我的实际代码,而是一个非常简单的示例来说明原理:

#define COMMAND_LIST              "list"
#define COMMAND_LIST_FIRST_CHAR   'l'
#define COMMAND_CHANGE            "change"
#define COMMAND_CHANGE_FIRST_CHAR 'c'
#define COMMAND_EXIT              "exit"
#define COMMAND_EXIT_FIRST_CHAR   'e'

switch(received_command_string[0]){
  case COMMAND_LIST_FIRST_CHAR:
    // Do the "list" stuff
    break;
  case COMMAND_CHANGE_FIRST_CHAR:
    // Do the "change" stuff
    break;
  case COMMAND_EXIT_FIRST_CHAR:
    // Do the "exit" stuff
    break;
}

用户“pmg”在gcc文档中找到了这个: “没有办法将宏参数转换为字符常量。”

我希望这些定义位于包含文件中,该文件可以由多个源文件共享。这是尽可能接近的,只有在一个地方定义了每个字符:

#include <stdio.h>
#define CH0 'F'
#define CH1 'o'
#define CH2 'o'
#define CH3 ' '
#define CH4 'b'
#define CH5 'a'
#define CH6 'r'
static char MY_STRING[] = { CH0, CH1, CH2, CH3, CH4, CH5, CH6, '\0'};
#define MY_STRING_FIRST_CHAR CH0

void main(void){
  printf("The string is %s, the first char is %c\n", MY_STRING, MY_STRING_FIRST_CHAR);
}

我不会这样做。最初的问题是,是否可以共享一个定义以获得字符串常量和字符常量。通过在运行时浪费时钟周期,我的问题有几种解决方案。

3 个答案:

答案 0 :(得分:3)

你可以这样做,只需写一次符号......但不同的定义

#include <stdio.h>

#define COMMAND_LIST_FIRST_CHAR   'l'
#define COMMAND_LIST              (char[]){ COMMAND_LIST_FIRST_CHAR, 'i', 's', 't', 0 }

int main(void) {
    char received_command_string[] = "list";
    switch (received_command_string[0]) {
        case COMMAND_LIST_FIRST_CHAR:
            printf("Doing the \"list\" stuff for '%s'\n", COMMAND_LIST);
            break;
        default:
            break;
    }
    return 0;
}

答案 1 :(得分:1)

为什么你绝对想要使用开关盒?

相反,您可以使用与您的字符串和处理函数匹配的映射表。然后你只需要遍历表格。

typedef struct {
    char * key;
    void (func*)(void);
} MAP_ENTRY;

MAP_ENTRY map [] = {
    {"list", listHandler},
    {"change", changeHandler},
    {"exit", exitHandler},
};

for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) {
    if (map[i].key[0] == received_command_string[0]) {
        map[i].func();
        break;
    }
}

然后您只需将处理代码从您的开关/案例移动到相应的处理函数

答案 2 :(得分:-4)

#define MY_STRING "Hello"

const char var[] = MY_STRING;

switch(var[0]) {
    case 'H':
    break;
    case 'A':
    break;
}

这应该解决它。