Как я могу конвертировать между enum и cstring без карты? - PullRequest
0 голосов
/ 26 июня 2018

Я уже видел этот ответ раньше, но использовал карту или векторы, но я не могу использовать внешние библиотеки для своего проекта, поэтому мне нужно найти другой способ. Для преобразования в cstring я использую функцию со случаем переключения, и она работает, но для преобразования cstring в перечисление не идет, как планировалось.

Метод, который я придумал для преобразования cstring в enum, заключается в том, чтобы сначала привести enum к int (none, first, second и т. Д. Становится 0, 1, 2 и т. Д.), Чтобы я Можно использовать цикл for для перебора различных перечислений. Затем, используя функцию enum to cstring, я сравниваю передаваемую строку со строкой, заданной функцией преобразования. Если они равны, перечисление установлено. Это кажется довольно запутанным способом сделать это, и неудивительно, что я не могу заставить его работать.

Вот весь мой тестовый код, функция setType - это то, где что-то идет не так.

enum type { none, first, second, third, fourth };

const char* typeName(type name);
type setType(char* name);                   // trouble here
int myStrComp(const char *str1, const char *str2);  // compare cstrings

int main() {                                // test the function
    char testName[] = "second";
    type testType = setType(testName);
    std::cout << typeName(testType) << std::endl;   // should print "second"
}

const char* typeName(type name) {           // convert enum to cstring
    switch (name) {
    case none:      return '\0';        break;
    case first:     return "first";     break;
    case second:    return "second";    break;
    case third:     return "third";     break;
    case fourth:    return "fourth";    break;
    }
}

type setType(char* name) {
    type temp;
    for (int i = 0; i < 4; i++) {       // I know, inefficient
        temp = static_cast<type>(i);    // but there's only 5 to check
        if (myStrComp(name, typeName(temp)) == 0) {
            return temp;
        }
    }
    return none;    // shouldn't get here
}

int myStrComp(const char *str1, const char *str2) {
    while (*str1 == *str2) {
        if (!*str1) {
            return 0;           // strings are equal
        }
        str1++;
        str2++;
    }
    return *str1 - *str2;   // how different are they alphabetically
}

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Чтобы ответить на ваш вопрос , вы можете связать enum s с текстом, используя таблицу поиска:

struct Entry
{
  type  enum_type;
  const char * enum_text;
};

Entry enum_conversion_table[] =
{
    {none, "none"},
    {first, "first"},
    {second, "second"},
    {third,  "third"},
    {fourth, "fourth"},
};
static const size_t conversion_table_capacity =
    sizeof(conversion_table) / sizeof(conversion_table[0]);

Преобразование из enum в текст:

  1. Поиск в таблице записи по ключу enum.
  2. Возвращает указатель на текстовое поле записи, если найдено, или nullptr, если не найден.

Преобразование из текста в enum:

  1. Поиск в таблице записи с текстом перечисления ключей.
  2. Вернуть значение перечисления, если оно найдено, или создать другое значение перечисления для «unknown» и вернуть его.

Эта техника:
1. Не использует библиотеки.
2. Данные могут быть помещены в секцию постоянных данных и сохранены в постоянной памяти.
3. Код может напрямую обращаться к данным.
4. Данные инициализируются до main().

0 голосов
/ 26 июня 2018
case none:      return '\0';        break;

Здесь есть одинарные кавычки, поэтому он возвращает символ \0, который как целое число равен 0. При преобразовании в указатель это нулевой указатель . При попытке разыменовать нулевой указатель в myStrComp(), происходит нарушение доступа .

Вместо этого вы можете использовать return ""; для возврата пустой строки.

Возможный способ упростить typeName - использовать массив:

const char* typeName[] = {"", "first", "second", "third", "fourth"};
if (myStrComp(name, typeName[i]) == 0) 

(Это приведет к нарушению доступа, если i выходит за пределы.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...