cin nicht sehen



  • Ich will einen Chat programmieren (welches in der konsole läuft)
    Es klappt auch alles - bis auf ein kleines Problem:
    Wenn ich was verschicken will tippe ich die Nachricht ein. z.B."hallo wie geht es dir?"
    So jetzt schickt der gesprächspartner mittendrin ein "hi"
    Sieht dann so aus:

    hallo wie ge
    Message recieved form 192.xxx.xxx.xx: hi
    ht es dir
    

    ich hab mir gedacht ich umgehe dieses problem indem ich was man eintippt verstecke. Wie ein passwort - d.h. man sieht erst was man verschickt hat, wenn man enter gedrückt hat weil es dann ausgegeben wird
    Kennt jmd eine möglichkeit die eigene eingabe zu verstecken (á la passwort)
    oder fällt jmd. vielleicht eine elegantere MEthode ein?
    ICh will nicht ins fenster (also Windowsfenster) - das würde den Rahmen meines "rumprobieren" sprengen

    Danke schon mal

    P.S.: ich weiß ich bin schon in einem fenster aber ich hoffe ihr wisst was ich meine 😉


  • Mod

    Das ist nicht ohne fortschrittlichere Mittel möglich. Dein C++ Programm kümmert sich nämlich nicht selbst um die Eingabe sondern das macht die Konsole (oder das Fenstersystem) in dem dein Programm läuft und die schicken die Eingabe dann an das Programm. Um Einfluss darauf zu nehmen, wie die Eingabe abläuft, muss dein Programm mit der Umgebung in der es läuft kommunizieren. Das ist natürlich möglich, bedarf aber des Einsatzes von externen Bibliotheken, deren Verwendung man erstmal lernen muss.
    Leider sind die gängigen Konsolen zueinander ziemlich inkompatibel, so dass man leider nicht eine Bibliothek für alles nehmen kann - du musst dich auf eine Konsole festlegen. DOS/Windows-Konsole? Hier wird oft die conio.h Bibliothek benutzt. POSIX-Terminals? ncurses ist eine beliebte Bibliothek dafür.



  • ok, das sprengt eindeutig den rahmen 😃 ^^
    jmd. vielleicht eine andere idee, wie ich dieses problem lösen kann?
    Kurze Erklärung: ich habe 2 threads laufen
    im 1. (mainthread) wird einfach nur auf eine eingabe gewartet und diese dann verschickt
    im 2. wird auf ein packet gewartet und dieses dann ausgepackt und gepostet



  • Das Problem ist ja, dass du nicht so einfach herausfinden kannst, ob der Benutzer gerade etwas am eingeben ist. Sonst könnte man ja mit dem Paket warten, bis das nächste Mal Enter gedrückt wird (oder gleich posten, falls der Benutzer nichts eingibt).

    Blöd ist natürlich auch, dass du das selbe Fenster zur Ein- und Ausgabe benutzt. Wenn du an Chatprogramme denkst, die haben alle ein separates Ein- und Ausgabefeld.

    Ich fürchte, mit Standard-C++ kommst du hier nicht wahnsinnig weit... Falls du das doch verbessern willst, ist die Frage, was für eine Bibliothek. Eine verbesserte Konsole? Oder eine 2D-Grafikbibliothek? Oder direkt eine GUI?


  • Mod

    Ich sag mal so: Wenn du in der Lage bist, vernünftig mit Threads und Netzwerkverbindungen zu programmieren, dann sollte ein kleines Fenster mit einem Aus- und einem Eingabebereich eigentlich keine große Sache sein.



  • Alternativ könnte man die Ausgabe in eine Datei umleiten. Ich stelle mir da eine HTML-Datei vor, die sich alle paar Sekunden aktualisiert. Dann könnte man die Eingabe im Konsolenfenster machen und die Ausgabe in der Webseite ansehen.

    Damit hätte man dann trotzdem ein Erfolgserlebnis und kann auch etwas visueller arbeiten ohne tatsächlich mit GUI in Kontakt zu kommen.



  • Wie wärs denn so? Ist zwar nicht besonders schön, aber eine Möglichkeit

    string readInput (char replace = '')
    {
        string eingabe;
        char now = '\0';
    
        while(now != '\r')
        {
            now = getch();
    
            if(now == 0)
            {
                getch();
                continue;
            }
    
            // Steuerzeichen ignorieren (Haben ASCII-Codes kleiner als 32)
            if(now < 32)
                continue;
    
            // Zeichen anhängen und Ersatzzeichen ausgeben
            eingabe += now;
            cout << replace;
        }
        cout << endl;
        return eingabe;
    }
    

    Das man danach den ganzen String ausgibt und der vorher nur diese Ersatzleerzeichen



  • Du könntest, sobald der Nutzer ein oder mehrere Zeichen eingetippt und noch nicht abgeschickt hat, die Ausgabe von eingegangenen Nachrichten verzögern bis der Benutzer die eigene Nachricht abschickt. Das sorgt aber dafür, dass die Nachrichten des anderen u.U. erst verzögert gelesen werden.
    Bei deiner Variante kann man Geschriebenes nicht wieder löschen und bemerkt keine Tippfehler etc.
    Daher ist die einzig komfortable Lösung wohl eine mit zwei Fenstern - eins für die Eingabe und eins für das komplette Gespräch wie bei normalen InstantMessagern der Fall. Dafür kannst du eine GUI erstellen oder mit (OS-abhängigen) Mitteln in der Konsole zwei Bereiche simulieren.



  • wx++ schrieb:

    Du könntest, sobald der Nutzer ein oder mehrere Zeichen eingetippt und noch nicht abgeschickt hat, die Ausgabe von eingegangenen Nachrichten verzögern bis der Benutzer die eigene Nachricht abschickt. Das sorgt aber dafür, dass die Nachrichten des anderen u.U. erst verzögert gelesen werden.

    Ich würde das mit zwei Threads lösen. Ein Thread wartet auf die Eingabe einer ganzen Zeile und sendet diese dann ab. Der andere Thread liest ankommende Nachrichten und speicher sie in eine geeignete Datenstruktur. Wird also eine Nachricht abgegeben werden alle Nachrichten in dieser Datenstrktur ausgegeben und anschließend aus dieser entfernt. So gehen keine Nachrichten verloren und man verhindert ein verzögertes Einlesen. Problematisch ist nur die Synchronisation der Threads.



  • SeppJ schrieb:

    Ich sag mal so: Wenn du in der Lage bist, vernünftig mit Threads und Netzwerkverbindungen zu programmieren, dann sollte ein kleines Fenster mit einem Aus- und einem Eingabebereich eigentlich keine große Sache sein.

    An sich hatte ich ja nur vor einbisschen mit Netzwerkprogrammierung rum zu experimentieren 😉
    -> also das SFML-Network-Tutorial-Bsp zu erweitern.
    Aber soweit ich das sehe gibt es nur die beiden mögl. entweder ins große Fenster zu springen (was an sich auch eine gute Übung währe - dazu gleich ein paar fragen) oder das ganze extern auszugeben (HTML-Seite).
    Gibt es die mögl. 2 (Konsolen)Fenster zu nutzen?
    1 für die ein - 1 für die Ausgabe?
    Oder gibt es eine mögl. den "Cursor" der Konsole/bzw die Tastatur zu Steuern? (à la: Force POS1; FORCE TASTEUP; cout Message; FORCE TASTEDOWN; FORCE ENDl;)
    Und dann noch eine Frage zum Fenster:
    Wie benutze ich Windowstextfelder? Muss ich ins Windowsfenster oder kann ich die auch in ein z.B. SFML Fenster implementieren?



  • greece57 schrieb:

    Gibt es die mögl. 2 (Konsolen)Fenster zu nutzen?
    1 für die ein - 1 für die Ausgabe?
    Oder gibt es eine mögl. den "Cursor" der Konsole/bzw die Tastatur zu Steuern? (à la: Force POS1; FORCE TASTEUP; cout Message; FORCE TASTEDOWN; FORCE ENDl;)
    Und dann noch eine Frage zum Fenster:

    Das ist jeweils Platformabhängig.



  • greece57 schrieb:

    Wie benutze ich Windowstextfelder? Muss ich ins Windowsfenster oder kann ich die auch in ein z.B. SFML Fenster implementieren?

    Du kannst sie innerhalb von SFML-Fenstern implementieren. Einfach ein Rechteck zeichnen und mit Text füllen. 🙂

    Eine fertige GUI besitzt SFML aber nicht.


Anmelden zum Antworten