Warum nutzt switch case keine Strings??



  • Hallo,

    also ich wollte folgendes billiges programm mit swithc case machen...aber mir scheint das er string nicht mag

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main()
    {
    
         string Daniel="Daniel";
         string Giacomo="Giacomo";
         string Tim="Tim";
         strin name;
    
         cout<<"Geben sie einen Namen ein!(Tim,Giacomo,Daniel)"<<endl;
    
         cout<<endl;
    
         cout<<"Der PC vollendet den Namen mit dem passenden Attribut"<<endl;
    
         cin>>name;
    
         switch(name)
         {
             case Daniel: cout<<" er stinkt sehr arg"<<endl;
    
             case Giacomo: cout<<" ist leider ein bissel zu dick"<<endl;
    
             case Tim: cout<<" ist sehr schlau aber komisch"<<endl;
    
             default: cout<<"Diesen Namen gibt es nicht"<<endl;
         }
    
    }
    

    vieleicht könnt ihr mit helfen warum das nicht geht



  • weil der ausdruck, den switch auswertet, ein ganzzahliger Datentyp sein muss (countable IMHO)

    Sollte der Compiler auch entsprechend sagen



  • strings gehen nicht in case, wie bereits gesagt. dafür kannst du aber ne map verwenden:

    #include <map>
    using namespace std;
    
    //in der main
    map<string,string> sprueche;
    sprueche.insert(make_pair("Threadstarter","schreibt doofe Sprueche"));
    
    string name;
    cin>>name;
    
    map<string,string>::iterator spruch=sprueche.find(name);
    if(spruch!=sprueche.end())
    {
        cout<<spruch->second;
    }
    


  • naja... könntest du mir dein code noch erklären weil der is mir ein bissel unklar??



  • Also kurz zur Erklärung:

    std::map<key, value> stellt eine Liste in Form von Wertepaaren zur Verfügung, und über den "key" kannst du mittels der Funktion find die Einträge suchen. Dazu muss aber das Konzept der Iteratoren verstanden werden; die STL definiert zu jeder Containerklasse Iteratoren die dazu dienen auf ein einzelnes Element zu zeigen, und die "durchiterieren" sprich über die Liste laufen können.

    Find liefert einen solchen Iterator zurück, der entweder auf ein gültiges Element oder das Listenende [sprueche.end()] zeigt, um noch genauer zu sein, als Listenende ist die Position hinter dem letzten Element gemeint, daher prüft man vor dem Zugriff immer ob end() erreicht wurde.

    cu André



  • Alternativ könntest du dir auch ein String-Switch selber bauen, ist aber natürlich nicht so komfortabel (und fehleranfälliger) als der normale switch.

    int switchStr( const char* strSwitch, const char* str1, ... )
    {
        const char** ppStr = &str1;
        for ( int i=0; ppStr[i]; i++ )
            if ( 0 == strcmp( strSwitch, *ppStr ) )
                return i;
        return -1;
    }
    
    ...
    string name;
    cin>>name;
    
    switch ( switchStr( name.c_str(), "Harald", "Georg", "Julia", NULL ) ) // Das letzte muss NULL sein, sonst Kabumm
    {
        case 0: // Harald
            break;
        case 1: // Georg
            break;
        case 2: // Julia
            break;
        default: // was anderes
            break;
    }
    

    ist aber nicht getestet 😃

    // Edit: Doofes .c_str() 🙂



  • @Badestrand:
    Und Du bist Dir sicher, dass Plattform X die Zeiger sequentiell aufsteigend im Speicher ablegt? 😉



  • Wenn schon so ein Hack dann benutz doch biete die varg-makros.



  • aber ich sage ma... kann man denn mein problem nicht einfacher lösen, also mit ifs habe ich es auch probert aber so richtig net hinbekommen... weil da muss ich doch nicht unbedingt sowas "kompliziertes"nehmen, wenns einfacher geht...aber ich weiß halt net wie genau



  • Was bitte hast du mit "if" nicht hinbekommen?

    std::string foo = blubb();
    if (foo == "sepp")
       { ... }
    else if (foo == "didumm")
       { ... }
    else if (foo == "blah")
       { ... }
    else
       { ... } // irgendwas anderes
    


  • lolz schrieb:

    Wenn schon so ein Hack dann benutz doch biete die varg-makros.

    Oder ',' überladen. 😉

    int switch_str(std::string const& compare, arg_array const& args)
    {
        int ret = 0;
        for (arg_array::const_iterator i = args.begin(); i != args.end(); ++i, ++ret)
            if (compare == *i)
                return ret;
    }
    
    switch(switch_str("Test", arg_array() = "Dies", "ist", "ein", "Test")) {
        case 0: // ...
    }
    

    'arg_array' zu implementiert als Übung für den Leser. 😉 (Ist nicht schwer ...)



  • jop jetzt gehts...habe nur die ifs... falsch angewendet.



  • darthdespotism schrieb:

    weil der ausdruck, den switch auswertet, ein ganzzahliger Datentyp sein muss (countable IMHO)...

    hmmm, ich denke, da spielt auch das "case" mit rein. Der Ausdruck beim case muss nämlich zur Compilezeit auswertbar sein ... und damit fallen zur Laufzeit erzeugte Objekte schonmal weg.

    Gruß,

    Simon2.


Anmelden zum Antworten