-1

I want to use a case "name" .

char arg1[256];
one_argument(argument, arg1, sizeof(arg1));

if(*arg1)
{
    switch(LOWER(*arg1))
    {
        case 'anime':
        {

        }
        break;
    }
}

When i call command do_reload anime not work. do_reload is main function and 'anime' is case. If i use case 'a' it works perfect but when i use case 'anime' nothing happen. Why this ?

Mark
  • 3
  • 1
  • 5

6 Answers6

2

As others have stated, you can't use text literals with case statements.

Your alternatives are:

  1. Lookup table with text and function pointers.
  2. std::map with function pointers.
  3. The if/else-if/else ladder.

Note: One issue with std::map or lookup table is that all function must have the same signature. The C++ language doesn't allow for different types of function pointers in a std::map or structure (lookup table).

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • Note on the note: Some of the hassle of same signature might be mitigated with a `std::map` of `std::function` and using `std::bind` or lambdas to hide the parameters. Emphasis on *might*. – user4581301 Aug 06 '16 at 00:34
  • One variation on with `std::map` is to map the string to an integer or enum value, then have a switch statement using that value. This gets around the issues with needing extra functions which may have different signatures. – 1201ProgramAlarm Aug 06 '16 at 03:57
1

I'm assuming you intended to use double quotes "" for string literals, as single quotes are for char.

Switches need to be able to choose a matching condition from a selection of integral (i.e. enumerable) constants. String literals, like "anime", boil down to a const char array in reserved memory to which char* pointers can be assigned. But comparing two strings is only meaningful by comparing their contents and not pointer addresses. It could happen that you create a dynamic string with the same contents as a string literal, but different address. Because of this ambiguity, you cannot use strings in switches.

You should use an if-else ladder, or a data structure that suits your needs likestd::map.

alter_igel
  • 6,899
  • 3
  • 21
  • 40
1

The expression in a switch, and the case values are only permitted to be of integral type.

A string literal is not of integral type.

A single character (like 'a') is of integral type. The literal 'anime' (although it doesn't make sense) is a multi-character literal, which also has an integral type.

Peter
  • 35,646
  • 4
  • 32
  • 74
1

From C++ switch statement doc:

condition - any expression of integral or enumeration type, or of a class type contextually implicitly convertible to an integral or enumeration type, or a declaration of a single non-array variable of such type with a brace-or-equals initializer.

I can't find a formal doc right now but the same applies to C language. So the answer is no, you can't do it in C++ neither in C

You can be interested in this SO question and answer - Why switch statement cannot be applied on strings?

Community
  • 1
  • 1
mvidelgauz
  • 2,176
  • 1
  • 16
  • 23
0

Unfortunately, you cannot switch on a string in C++.

Jesse
  • 73
  • 6
0

Just because there are so many answers saying you can't, I'm going to tell you -- you sure can! With some caveats of course.

constexpr unsigned long encode_(unsigned long in, const char* s)
{
  return *s ? encode_((in << 8) | s[0], s + 1) : in;
}

constexpr unsigned long encode(const char* s)
{
  return encode_(0, s);
}

constexpr unsigned long operator"" _x(const char* s, long unsigned len)
{      
  return encode(s);
}

int main(int argc, char **argv)
{
  auto x = "hello"_x;
  switch (x)
  {
    case "ola"_x:
      break;

    case "hello"_x:
      break;
  }
}

What this code does is it stuffs the characters of your string name into a long integer. This solution is only guaranteed to work for strings of upto 8 characters on a 64-bit system. After that the encoded numbers won't be guaranteed to be unique. To safeguard against inadvertent use of a longer string, I would recommend checking the len argument in the user-defined literal function and causing a compilation error if a longer string is used. Or you can tweak the code a bit and require that the first 8 characters of each string should be unique.

It should be relatively easy to extend my code to the case of 5 bits per lower case english character to increase the length of strings you can use to 13 from 8.

Shannon showed that the english language uses between 0.6 and 1.3 bits per letter in ordinary text. So a 64-bit integer can potentially store about a string of about 64 characters. Such a compression function is not easy to write as a constexpr function, but would be an interesting exercise.

Always Confused
  • 470
  • 4
  • 7
  • "I'm going to tell you -- you sure can!" No, you can't. Nice answer and yes it works but you end up using switch with integers. – DimChtz Aug 06 '16 at 21:45