Chat - Interpreter Programmieren
-
Hi,
ich möchte für ein Chatprogramm mit Winsock einen Interpreter für bestimmte Befehle schreiben.Beispiel:
Ich sende "MSGBOX User123 Wichtig Komm mal ins ICQ"
der Befehl würde lauten:
MSGBOX User Titel Nachricht,
und ich müsste das ganze jetzt zersetzen, also so etwa:1. mit find() MSGBOX finden, erkennen, dass eine MessageBox bei dem User erstellt werden soll
2. die Nachricht "zersetzen", nach User = User123, Title = Wichtig, Content = Komm mal ins ICQ
3. Die MessageBox erzeugen mit MessageBox(0, "Komm mal ins ICQ", "Wichtig", MB_OK);also,
1. Ist das mit String Funktionen machbar, oder gibts bessere Möglichkeiten?
2. Wenn String Funktionen die beste Lösung sind, könnt ihr mir ein paar hier gut anwendbare nennen?mfg
-
Schau dir mal find() und substr() an.
-
1. Ist das mit String Funktionen machbar, oder gibts bessere Möglichkeiten?
Die gibts immer

Du könntest eine ScriptSprache integrieren, wie AngelScript und MsgBox einfach als Funktion in Angelscript anmelden. Wenn die Eingabe des Users im Chat nun als Bsp. ein "/" vorne dran hat, dann sendest du das einfach als RawString an die ScriptEngine und die führt das aus.
Bsp:
/MsgBox("Komm mal ins ICQ", "Wichtig");
rya.
-
[quote="scorcher24 | off]...[/quote]Was soll hier der Vorteil einer Skriptsprache sein? Interpretieren lassen sich die Befehle in C++ genauso gut.
-
Okay, das mit substr() funktioniert, und ich kann auch einen Befehl auslesen - aber nur EINEN: (Pseudocode)
IF (Befehl = Msgbox)
{
pos = Befehl.find(MsgBox);
Parameter = Befehl.substr(pos + 7); // Msgbox = 6 Zeichen + Leerstelle
//...
}So, ab hier kann ich also dann direkt den Befehl verarbeiten, der "Msgbox" folgt.
Aber wie soll ich das mit 2 Parameter machen? Msgbox [Titel] [Nachricht]?
Muss ich dann da jeweils ein Zeichen davor setzen? Zb. Msgbox [/Titel] [/Nachricht]? Dann könnte ich ja direkt nach dem Zeichen suchen
-
Irgendwie so, ungetestet:
void MsgBox( const std::string& par ) { // Format: TITEL NACHRICHT // Erstes Leerzeichen finden size_t space_pos = par.find( ' ' ); if ( space_pos == std::string::npos ) throw std::exception( "Falsches Format beim MSGBOX-Befehl" ); // Titel und Nachricht extrahieren std::string title = par.substr( 0, space_pos ); std::string msg = par.substr( space_pos+1 ); // Irgendwie weiter verfahren.. } void Whatever( const std::string& par ) { ... } // Falls Kommando => Wird hier behandelt, gibt true zurück. // Sonst gibt false zurück bool HandleCommand( const std::string& command ) { // Handler aufsetzen typedef void(*HandlerFunc)(const std::string&); typedef std::map<std::string,HandlerFunc> Handler; static Handler handler; if ( handler.size() == 0 ) { handler["MSGBOX "] = &MsgBox; // Evtl ohne Leerzeichen, je nachdem handler["WHATEVER "] = &Whatever; ... } // Nach Kommando im Handler suchen for ( Handler::const_iterator i=handler.begin(); i!=handler.end(); ++i ) { size_t comm_size = i->first.size(); if ( command.size()>=comm_size && command.substr(0,comm_size)==i->first ) { // Gefunden, aufrufen i->second( command.substr(comm_size) ); return true; } } // Kein passender Handler gefunden return false; }
-
Arr0ws schrieb:
Ich sende "MSGBOX User123 Wichtig Komm mal ins ICQ"
der Befehl würde lauten:
MSGBOX User Titel Nachricht,kann man doch einfach eine Skriptsprache zu benutzen, die Funktionsargumente ohne Klammern übergeben kann, und dort eine kleine DSL implementieren, deren Befehle dann im Interpreter aufgerufen werden.
Ich denke da mal an Tcl oder Smalltalk.
In Tcl kannst du schreiben
proc MSGBOX {user titel nachricht} { ... sende an user die nachricht mit titel ... }und dann aufrufen mit etwas ähnlichem wie
MSGBOX bill "betr: wichtig" "doch nicht wichtig"In Smalltalk geht das ähnlich einfach, nur folgen die Argumente dann hinter Doppelpunkten:
msgbox user: bill sub: 'wichtig' msg: 'jetzt mal egal'
-
... natürlich nur, wenn Du hierfür nicht bereits auf C++ festgelegt bist.
-
Tausend Dank an bade_off! Dein Code war zwar nicht richtig, aber der hier geht
(Ich habs jetzt doch mit "-" vor den Parametern gemacht, damit Messageboxen mit Leerzeichen auch ausgegeben werden können):EDIT: Weil ich so nett bin, hier der ganze Code

#include <iostream> #include <string> using namespace std; string Input; string str1, str2; size_t pos; size_t pos2; int main() { while(true) { cout << "Input: "; getline(cin, Input); // Fehlerabfrage: // 1. Ist MSGBOX an Erster Stelle? // 2. Ist "-" an 7. Stelle? // 3. Sind 2 "-" vorhanden? if (Input.find("MSGBOX") == 0) { if (Input.find("-") == 7 && (Input.find("-") != Input.find_last_of("-"))) { pos = Input.find("-"); pos2 = Input.find_last_of("-"); str1 = Input.substr(pos + 1, pos2-9); str2 = Input.substr(pos2 + 1); cout << "\nMessagebox(0, \"" << str1 << "\", \"" << str2 << "\", MB_OK);\n\n"; } else { cout << "\nusage: MSGBOX -[TITLE] -[CONTENT]\n\n"; } } else { cout << "\nUnknown Command\n\n"; } } return 0; }