4

I'm working on a small project on Dev-C++. I'm trying to make a bot to ask you some questions, but I can't use the switch statetments with the strings. Every time I try to do so it shows error! I also tried to change the srings to normal int variables but when I the code runs all at once after answering the first question! Does anyone knows how to fix any of these situations?

Here is my code:

// #include "stdafx";

#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>

using namespace std;

int main()
{
    string comida;
    string nome;
    string idade;
    string pais;

    cout << "Ola, o meu nome e Aleksandar. Qual e o teu nome?" << endl; //Ask for nome
    cin >> nome; //Recieve variable nome

    cout << "Es de que pais, " << nome << "?" << endl; //Ask for pais
    cin >> pais; //Receive pais
    cout << pais << " e um pais bonito. " << "Eu sou de Portugal!" << endl; 

    cout << "Quantos anos tens " << nome << "?" << endl; //Ask for idade
    cin >> idade; //Receive variable idade

    switch (idade) {
       case 21:
          cout << "O meu irmao tambem tem 21 anos!" << endl;
          break;
    }
    cout << "Eu tenho 28" << endl;

    cout << "Qual e a tua comida preferida?" << endl; //Ask for comida
    cin >> comida; //Receive variable comida

    cout << "Tambem gosto muito de " << comida << ". Mas gosto mesmo e de Vatruchka!" << endl;
    cout << "Xau " << nome << "!" << endl;
}
4
  • 3
    And why use a switch where a simple if would do? Commented Feb 28, 2015 at 23:53
  • 3
    Short answer: you can't. C++ switches are only for integral (int, char, ecc.) constants. You might want to consider a std::map<string, std::function<void()>> Commented Mar 1, 2015 at 0:01
  • Why is your indentation all over the place? Commented Mar 1, 2015 at 0:16
  • 1
    Downvoted because one should search first (this question has been answered very often already) and the code contains a lot of noise – non-english stuff and generally a lot of code that doesn't have much to do with the question. Commented Mar 1, 2015 at 0:25

4 Answers 4

4

A switch will not compile when non-intergal (i.e. string, float, bool, vector, etc...) data-types are assigned to the switch's case: statements. Furthermore, its necessary that the values assigned to the case: statements are const.

In other words:

Switches must use "constant integral data-types" (i.e. 'enum', 'int', 'char', etc...), and cannot implament strings as conditional statements, however; that is not the same as saying that strings cannot be used in a conditional statement, they very much can be & often are — see the example below:


    std::string s;
    std::cin >> s;

    if (s == "Yes")
    {
       std::cout << "You said yes!" << std::endl;
    } 
    else if (s == "No")
    {
       std::cout << "You said no?"  << std::endl;
    }
    else 
    {
       std::cout << "You said something I don't understand"  << std::endl;
    }
So to finish this answer, you can see that you can achieve the same thing you could with a switch statement using if/else blocks. It may, or it may not, be ideal for your situation, but this is how C++, and switch statements work, so your stuck with it — like it, or not...
Sign up to request clarification or add additional context in comments.

3 Comments

In practice, most of the time I've needed to "switch" on a string, I've found a map to pointers to functions or polymorphic functional objects to be the best solution. (Most of the time. There have been a few exceptions where I've chained if...else if....)
Sure, but that is probably not the level of discussion the OP wants in this particular case.
Great answer. Terrible programming language.
2

If the string contains a number, switch(std::stoi(idade)) will work. But that doesn't work if idade contains something else.

9 Comments

And it means, of course, that you have to have a try block somewhere.
@Xiao: No security issue here. There's an implicit default: break.
@Xiao: Yes, that is how switch works. You are writing C++, not assembly. It's nowhere near as close to the metal as you seem to think!
@Xiao: Right, and it doesn't say "but some random piece of code that happens to be in your desktop computer's memory may be executed instead". C++ is an abstraction. It's a lot safer than you think. It will never, for a valid, well-defined program, result in arbitrary pieces of code being executed. I can't quote you the part of the standard that ensures that because it's spread all over the place. It's inherent.
@Xiao: And from an assembly perspective, "use as an index for the next instruction" doesn't make sense anyway. Consider case 0: !
|
1

You can't use strings — switch only works for integral case types (i.e. integers and enums).

You could use something like this, instead:

if (idade == "21") { cout << "...\n"; }
else if (idade == "something else") { cout << "...\n"; }

You describe that the code runs all at once when you change to using integers. It's possible you're forgetting to include break in each case clause.

Comments

-1

If you have a set of different strings that you are expecting then you can set up an enum and a map (I use the word map loosely here - I don't mean the actual map in C++, although I know it is possible to do something similar with it)

Use this to turn the input into an enum and then you can run a switch on the enum

E.g.

enum class ANSWER
{
    ANSWER_1,
    ANSWER_2
};

class AnswerMap    \\set up this class like a singleton
{
    std::vector<std::pair<std::string, ANSWER>> _answer_map = {
        std::make_pair("Answer 1 string", ANSWER::ANSWER_1),
        std::make_pair("Answer 2 string", ANSWER::ANSWER_2)
    }

    std::string String(ANSWER answer);    \\have this function loop through this->_answer_map until finding the pair with the second item as the given enum and return the corresponding string

    ANSWER Enum(std::string answer);    \\have this function do the same as this->String but find the pair where the string matches and then return the corresponding enum
}

2 Comments

this seems more complicated and slower than a map for no apparent reason
I used this when I had to make a solution and didn't have the time to spend learning how to use a map. It is slower but it wasn't the bottle-neck in my application so it didn't matter

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.