In einer Consolenanwendung ein "Menü" erstellen?



  • Hallo,

    ich hab mal ne Frage zur Konsolenanwendung!

    Und zwar möchte ich eine Art "Menü" erstellen.

    Es soll ca. so aussehen:

    1. 123
    2. xyz
    3. 456
    4. abc
    .
    .
    .

    Wenn ich nun die Ziffern vor der Schrift eingebe, soll nun bestimmte Punkte sich in der Konsole öffen.

    Also z.b bei einem Taschenrechner, bei 1. kann ich addieren, bei 2. Subtrahieren...

    Versteht ihr?!

    Danke für eure Hilfe!



  • Besser ins Konsolenforum, nich?

    Ist doch ganz einfach. Menü zeichnen, wenn Eingabe 1 dann Konsole löschen, neues Menü bzw. sonstwas zeichnen usw...

    MfG



  • Ehm joa sollte kein Problem sein:

    class menu
    {
    public:
        void push_back(std::string const& item) { m_data.push_back(item); }
        std::size_t get_selection() const { return m_sel; }
    
        friend std::ostream& operator <<(std::ostream& out, const menu& menu)
        {
            for (std::size_t i = 0; i < menu.m_data.size(); ++i) out << "(" << i + 1 << ") " << menu.m_data[i] << std::endl;
            return out;
        }
        friend std::istream& operator >>(std::istream& in, menu& menu)
        {
            do {
                std::cout << "Auswahl: " << std::flush;
                in.sync(); in.clear(); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            } while (!(cin >> menu.m_sel));
            --menu.m_sel;
        }
    private:
        std::vector<std::string> m_data;
        std::size_t m_sel;
    };
    
    int main()
    {
        menu inst;
        inst.push_back("Hilfe");
        inst.push_back("Beenden");
    
        std::cout << inst << std::endl;
        std::cin >> inst;
        switch(inst.get_selection())
        {
        case 0: std::cout << "Da kann ich ihnen auch nicht helfen!" << std::endl; break;
        };
    };
    

    ...



  • ceplusplus@loggedoff schrieb:

    Besser ins Konsolenforum, nich?

    Ist doch ganz einfach. Menü zeichnen, wenn Eingabe 1 dann Konsole löschen, neues Menü bzw. sonstwas zeichnen usw...

    MfG

    AH! Ich Trottel! Hab ich vergessen bzw übersehen!

    Sry!

    Hoffentlich kann ein Admin das bei Gelegenheit mal verschieben!

    (D)Evil schrieb:

    Ehm joa sollte kein Problem sein:

    class menu
    {
    public:
        void push_back(std::string const& item) { m_data.push_back(item); }
        std::size_t get_selection() const { return m_sel; }
        
        friend std::ostream& operator <<(std::ostream& out, const menu& menu)
        {
            for (std::size_t i = 0; i < menu.m_data.size(); ++i) out << "(" << i + 1 << ") " << menu.m_data[i] << std::endl;
            return out;
        }
        friend std::istream& operator >>(std::istream& in, menu& menu)
        {
            do {
                std::cout << "Auswahl: " << std::flush;
                in.sync(); in.clear(); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            } while (!(cin >> menu.m_sel));
            --menu.m_sel;
        }
    private:
        std::vector<std::string> m_data;
        std::size_t m_sel;
    };
    
    int main()
    {
        menu inst;
        inst.push_back("Hilfe");
        inst.push_back("Beenden");
    
        std::cout << inst << std::endl;
        std::cin >> inst;
        switch(inst.get_selection())
        {
        case 0: std::cout << "Da kann ich ihnen auch nicht helfen!" << std::endl; break;
        };
    };
    

    ...

    Okay! Ich versuche mich da mal durchzuhangeln!

    Thx!



  • Hallo,

    falls dir der Quelltext von (D)evil zu kompliziert scheinen soll, dann habe ich hier auch noch eine einfachere Variante, ein Menü zu erstellen (ohne Klassen, etc.):

    // local
        int menuSelect = 0;
    
        cout << "[ 1 ] Addieren"       << endl
             << "[ 2 ] Subtrahieren"   << endl
             << "[ 3 ] Multiplizieren" << endl
             << "[ 4 ] Dividieren"     << endl << endl
             << "Treffen Sie eine Auswahl: ";
        cin  >> menuSelect;
    
        switch( menuSelect )
        {
          case 1 : funcAdd(); // Funktion für Addition
                    break;
          case 2 : funcSub(); // Funktion für Subtraktion
                    break;
          case 3 : funcMul(); // Funktion für Multiplikation
                    break;
          case 4 : funcDiv(); // Funktion für Division
                    break;
    
          default: cout << "\nFalsche Eingabe!" << endl;               
        }
    

    Anstelle von Zahlen kannst du auch Zeichen benutzen. Das sieht dann ungefähr so aus:

    case 'a' : funcAdd();
    

    Ich hoffe, dass dir dieses einfache Beispiel ein wenig weiterhilft 🙂



  • Muss das jetzt in die Main Funktion?! 😞

    Also:

    #include <iostream>
    using namespace std;

    int main()
    {
    .
    .
    .
    }



  • Ja. Der Code hat aber nen paar Nachteile. Du kannst ihn nur durch Modifikation für ein anderes Menü wiederverwenden; wenn man mal 'a' eingibt will ich nicht wissen was das Programm dann macht; Bei falscher Eingabe geht es nicht wieder von vorne los 😉

    Von daher ... versuch dich mal durch meinen Code durchzubeißen 😃

    class menu
    {
    public:
        void push_back(std::string const& item) { m_data.push_back(item); } // Wert an internen vector übergeben ... (array)
        std::size_t get_selection() const { return m_sel; } // operator >> ließt m_sel ein. Damit wir das auch nutzen können brauchen wir nen getter.
    
        friend std::ostream& operator <<(std::ostream& out, const menu& menu) // bsw. std::cout << menu_inst << std::endl; ruft den operator auf.
        {
            for (std::size_t i = 0; i < menu.m_data.size(); ++i) out << "(" << i + 1 << ") " << menu.m_data[i] << std::endl; // gehe den ganzen Vektor durch und gib ihn jeweils aus. Dabei gibt er dir davor auch noch die jeweilige Item-ID aus. Sonnst wäre auch std::copy möglich.
            return out;
        }
        friend std::istream& operator >>(std::istream& in, menu& menu)
        {
            do {
                std::cout << "Auswahl: " << std::flush; // Auswahl: ausgeben.
    /**/
                in.sync(); in.clear(); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            } while (!(cin >> menu.m_sel));
    /* - so lange die Eingabe inkorrekt ist, zurücksetzen und nochmal versuchen */
            --menu.m_sel; // ein std::vector ist wie jeder array null indexiert.
        }
    private:
        std::vector<std::string> m_data;
        std::size_t m_sel;
    };
    


  • Crew06ZW schrieb:

    Muss das jetzt in die Main Funktion?! 😞

    Also:

    #include <iostream>
    using namespace std;

    int main()
    {
    .
    .
    .
    }

    ja



  • wenn du devils "menu" klasse verwendest, dann benutze die operator methode (die funktioniert)

    friend std::istream& operator >>(std::istream& in, Menu& menu) 
       { 
          do { 
             std::cout << "Auswahl: " << std::flush; 
             in.sync(); 
             in.clear(); 
             cin >> menu.m_sel;
          } while ( menu.m_sel< 1 || menu.m_sel > (int)menu.m_data.size() ); 
    
          --menu.m_sel;  
    
          return in;
       }
    


  • Wohl eher:

    friend std::istream& operator >>(std::istream& in, menu& menu)
    {
        do {
            std::cout << "Auswahl: " << std::flush; 
            in.sync(); in.clear(); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        } while (!(cin >> menu.m_sel) || menu.m_sel == 0 || menu.m_sel > (m_menu.m_data.size())); /* >= m_menu.m_data.size() + 1 */
        --menu.m_sel; 
        return in;
    }
    


  • (D)Evil schrieb:

    Wohl eher:... }[/cpp]

    oder so... wenn man sich das return sparen möchte... mir ging es hauptsächlich um das "return in"


Anmelden zum Antworten