Eigene Konsole schreiben



  • Guten Abend!

    Ich möchte in C++ wie das Thema schon sagte eine Eigene Konsole schreiben.
    Sie soll dann nachher durch verschiedene Befehle gesteuert werden.

    Meine Frage ist nun, wie öffnet man die Konsole sodass man die Befehle eingeben kann, die über eine Klasse/Methoden entstehen, auch verfügbar werden und nicht jeden Schritt im Quell-Code genau festlegen muss?

    EDIT:

    Also das das Programm praktisch Eigenständig darauf wartet das zum Beispiel der Befehl

    Auflisten(10,2,true)
    

    und dann die/das entsprechende Auflistet.
    Sonst müsste man ja immer schreiben

    cout << "Geben sie den befehl ein..." << endl;
    cin >> eingabe1;
    if (eingabe1 == Auflisten(10,2,true)
    { cout ".................und so weiter und so fort" }
    


  • Du müsstest die Eingaben, die der User macht, komplett parsen und dann interpretieren. Wie kompliziert das Parsen sein wird hängt vom Sprachschatz deiner Konsole ab. Der Rest drumrum ist vergleichsweise einfach: Prompt ausgeben, Befehlszeile einlesen, parsen, ausführen. Und das alles in einer Schleife...



  • Achso, ich werde mir deinen Beitrag mal kopieren und später darauf zurück kommen wenn ich meine C++ Kenntniss etwas erweitert habe ^^

    Aber Danke für deine recht zügige Antwort



  • Och, so schwer ist das gar nicht. Du solltest halt nicht damit anfangen, die beste Konsole/Shell der Welt zu schreiben, sondern eher in kleinen und schnellen Schritten vorwärts.

    Ich geb dir mal ne Struktur vor 🤡:
    1. Grundgerüst, also einfache Schleife, vor jeder Eingabe wird "> " (oder so) ausgegeben und du kannst Befehle einlesen (mit std::getline), ohne Parsing oder weitere Verarbeitung.

    2. Du implementierst super-einfache Befehle, z.B. "hallo" und "exit", wobei bei "hallo" auch irgendeine Begrüßung kommt, bei exit wird die Schleife und damit das Programm verlassen.

    3. Du überlegst dir eine gute Struktur, die Befehle zu verarbeiten ( if (str=="hallo") {...} else if (str=="exit") {...} wäre z.B. nicht gut). Evtl bietet sich hier eine map an, die Strings nach Funktionszeigern mappt. Dann kannst du mit if ( mymap.find(input) != mymap.end() ) rausfinden, ob der Befehl existiert und mit mymap[input](); die Funktion aufrufen, die dann den Befehl ausführt (also für jeden Befehl eine Funktion).

    4. Argumente für die Befehle parsen, also bis Klammer ist der Befehl, danach bis zur hinteren Klammer die Texte zwischen den Kommata extrahieren. Die Texte bzw Parameter in vector<string> oder so speichern und der entsprechenden Befehlsfunktion mit übergeben. Die wertet die Parameter dann aus, also wandelt sie in entsprechend be-typ-te Variablen um und agiert dann je nach Parametern.

    Oder so 👍



  • Also Danke erstmal für deine bestimmt sehr ausführliche Antwort.

    Nur leider bin ich sowas von Müde, das ich im Moment eine lange Leitung habe 😕 und den ganzen Text nur Teilweise verstanden habe. 😃

    Also Ich lese ihn heute Nachmittag nochmal und binde ihn in meine Konsole ein.

    Aber ich habe mir das ungefähr so vorgestellt:

    #include <cstdlib>
    #include <iostream>
    #include <string>
    
    using namespace std;
    // Die Klassen
    class Konto {
                public:     
                       const string ktonummer;
                       double kontostand;       
                       string inhaber;
    
                        // Konstruktoren innerhalb der Klasse
                        Konto(string ktonr);                  
                        Konto(double betrag, string ktonr);       
    
                        //Methoden innerhalb der Klasse                      
                        void standAuslesen();
                        void ktonrAbfragen();  
    };      
    
    // Konstruktor
    Konto::Konto(string ktonr):
        //Initialisierung
        ktonummer (ktonr),
        kontostand(0)                                    
    {                       
            cout << "Konto wird eroeffnet" << endl;                                                         
    }
    
    Konto::Konto(double betrag, string ktonr):
        //Initialisierung                       // Die Initialisiererlisten können unter
        ktonummer (ktonr),                      // anderem konstante Werte definieren!
        kontostand(betrag)                      // Außerdem erhöht sie die Perfomance.            
    {
        kontostand = betrag;          
        cout << "Konto wird eroeffnet" << endl;
    }
    
    // Methoden
    void Konto::standAuslesen()
    {
    cout << "Kontostand: " << kontostand << endl;
    }
    
    void Konto::ktonrAbfragen()
    {
    cout << "Ihre Kontonummer ist: " << ktonummer << endl;
    }
    
    // Hauptprogramm
    int main(int argc, char *argv[])
    {
        Konto kto( 11.50 , "0001" );     
        kto.standAuslesen();
        kto.ktonrAbfragen();
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    Den Code habe ich zwar nicht ganz alleine verfasst, aber ich verstehe in ganz!
    und so dachte ich mir das:
    Ich wollte mit den Klassen verschiedene Befehle einrichten die ich dann in der Shell ausführe, aber das überlege ich mir halt heute Nachmittag wie ich das am geschicktesten anstelle



  • Hm wie wärs wenn man die Befehle einfach entgegen nimmt und in std::string speichert.Und das dann am besten in ne Zahl umwandeln und dann für die Befehle Zahlen festlegen und dann mit ner Switchanweisung abfragen, was eingetippt wurde und dann dementsprechend handeln?
    (String in Int verwandeln hab ich zwar selbst noch nicht gemacht, aber wurde glaub ich schon ein paar mal Threads dazu erstelllt...kannst ja mal gcuken)

    Nur so ne Idee von mir

    mfg
    Finn


  • Mod

    Finn schrieb:

    Hm wie wärs wenn man die Befehle einfach entgegen nimmt und in std::string speichert.Und das dann am besten in ne Zahl umwandeln und dann für die Befehle Zahlen festlegen und dann mit ner Switchanweisung abfragen, was eingetippt wurde und dann dementsprechend handeln?
    (String in Int verwandeln hab ich zwar selbst noch nicht gemacht, aber wurde glaub ich schon ein paar mal Threads dazu erstelllt...kannst ja mal gcuken)

    Nur so ne Idee von mir

    mfg
    Finn

    Dann wird das aber schwierig, falls die shell später mal mehr als nur einfache interne Befehle verarbeiten soll.



  • Sie soll eigentlich so eine Art Mathematik Datenbank werden, also

    Es gibt eine Klasse Mathe. In dieser Klasse sind z.B. Quadrat, Rechteck, Dreieck.

    So wenn man nun die Methode Flächeninhalt aufruft und die Länge und Breite des Rechteckes an diese Methode mit Parametern/Argumenten übergibt dann soll er den Flächeninhalt ausrechnen.

    Das ganze soll natürlich komplexer werden und viel mehr ausrechnen können als nur Flächeninhalt.



  • Na dann kannst dus sdoch auch so machen:
    Einfach mit cout ausgeben was es für Wahlmöglichkeiten gibt und dann soll man z.B. für die Flächenberechnung von nem Dreieck die '1' drücken...oder halt für was anderes die 2,3,...etc.
    Und nachdem du dann mit ner switchanweisung herausgefunden hast, was der Benutzer eigetnlich will, dann starte in diesem Fall jetzt einfach die Funktion Dreiecksfläche_berechnen();..nur als Beispiel
    (So oder so ähnlich kannstes ja machen...außerdem is das Benutzerfreundlicher als so ne Konsole mit befehleingaben^^)
    mfg
    Finn



  • Finn schrieb:

    [...]
    So oder so ähnlich kannstes ja machen...außerdem is das Benutzerfreundlicher als so ne Konsole mit befehleingaben^^

    ARGH! Nur weil die Windows-Konsole Benutzerunfreundlich ist, heißt es noch lange nciht, dass Konsolen(-artige) Benutzerunfreundlich sind!
    Ich bedauere schon den armen Programmierer, der ein neues Kommando einfügen soll. Erst in dem switch rumwühlen, dann nen neuen Menüpunkt hinzufügen, usw. Unnötig und Fehleranfällig.

    Außerdem wird das verdammt unhandlich für den Anwender, wenn es mal mehr als 10 Kommandos gibt. Und die Parametereingabe ist unter aller Sau.
    Um zu addieren muss der erste Parameter abgefragt werden, dann der zweite, ab hier immer wieder nach nem neuen. USW.

    Hier ist definitiv deine Herangehensweise benutzerunfreundlich 😉
    Oh, mach ein Kommando "help", mit dem man sich alle Kommandos anzeigen lässt, und "help $kommando" um Hilfe zu dem Kommando anzuzeigen. Letztere kommt natürlich aus der Kommandoklasse selber.



  • Hi, Finn deine Idee ist im Grunde zwar nicht schlecht, aber für mein Projekt eher nicht sinnvoll. Es soll ja nicht nur Flächenberrechnung sein, wenn später dann nochmal Berrechnung der Höhe, Satz des Pythagoras, usw. dazu kommt wird es sehr unübersichtlich, einerseitz für den Benutzer, aber auch für den Programmierer wenn er mal das Programm weiter schreiben will.



  • So, ich habe schon mal angefangen mit dem schreiben des Programmes.
    Ich bin natürlich noch laaange nicht fertig aber das ist der Grobe aufbau wie ich es machen werde (Alles noch ohne Konsole und damit noch total unflexibel).

    Das Programm


Anmelden zum Antworten