[C++] Aus Array einen String machen

Blaggi

Grünschnabel
Ich bin gerade dabei einen kleinen IRC Bot zu bauen, der sich einfach auf den Server verbindet und bisschen herumhängt..

Allerdings muss ich am anfang dem Server einen PONG senden, mit der Zeichenfolge die er mir vorher gesendet hat.

Das ganze sieht dann so aus:

*** Looking up Hostname
*** Found your Hostname
*** Looking up identd
*** No identd found
PING 156748AV14

Und dann muss ich
PONG 156748AV14

Senden, damit ich nicht sofort wieder getrennt werde.

Mein Codeteil zum empfangen sieht zurzeit so aus:
Code:
	char ausgabe[1000];
	int x = 0;

	while(1)
	{
		x = recv((SOCKET)sock, ausgabe, 1000, 0);
		
		if(x > 0)
		{
	            	ausgabe[x] = 0;
			cout<< ausgabe << endl;
		}
		Sleep(10);
	}
(Aus dem Tutorial auf dieser Seite)

Ich muss mittels substr(); prüfen, ob die ersten 4 Zeichen "PING" sind, und wenn das passt, den Rest (also die Zeichenfolge) extrahieren..
Nur kann ich nicht substr auf ein Array anwenden (Zumindest hat mich DevC++ immer angemeckert)

Gibt es da ne möglichkeit, es aus dem Array zu lesen, oder das Array so umzuformen, dass ich es mit substr() lesen kann?
Wäre auch ganz nett, wenn es nicht eine Lösung mit riesigem Aufwand wäre, da ich das selbe für alle Befehle machen muss, die mein Bot dann im IRC bekommt (!time usw usf)
 
Zuletzt bearbeitet:
um einen String aus Deinem Array zu machen kannst Du
std::string strTemp = ausgabe.

Schneller ist aber folgendens

if (strstr(ausgabe,"PING"))
//send PONG

Gruß
Gerhard
 
thx, klappt sehr gut =)

Aber ein weiteres Problem ist, wie prüfe ich ob ein String in einem String ist, ohne strstr zu benutzen? Bis jetzt hat das nie geklappt

Das ist relativ wichtig, damit nicht einer im Channel einfach nur JOIN sagen muss, damit der Bot anschlägt:
Code:
if((strstr(strTemp, "JOIN") && (!strstr(strTemp, "PRIVMSG #"))

Da gibt er mir nen Fehler aus:
"no matching function for call to `strstr(std::string&, const char[5])' "

Ich habe schon versucht ein Char Array zu machen:
Code:
char* testNeedle[2];

testNeedle[0] = "JOIN";
testNeedle[1] = "PRIVMSG #";
Klappt auch nicht =/

Gibts da villeicht eine bessere Lösung?
In C# hab ich sowas mit string.Contains() gelöst, gibt es in C++ was ähnliches, aber anders als strstr()?
 
Hallo,

entscheid dich am besten mal, ob du mit C-Strings (char *) oder mit C++-Strings (std::string) arbeiten willst. Wenn du ständig beides vermischst, wirst du nämlich auf Dauer nicht glücklich. Auf der unteresten Ebene wirst du wohl um C-Strings nicht herumkommen (wegen Winsock), aber spätestens bei der Weiterverarbeitung solltest du dann konsequent entweder auf das eine oder auf das andere setzen. Wegen der leichteren Handhabung würde ich persönlich zu std::string greifen.

Grüße,
Matthias
 
tobee hat gesagt.:
Wie wilsst du nicht strstr benutzen.
Ist doch eigentliche die gängige Methode?

Ich hab doch bereits geschrieben, dass strstr IMMER fehler ausgibt...

Code:
no matching function for call to `strstr(std::string&, const char[5])'

@Matthias: Ich habe den Code wie gesagt hier aus den Tutorials, und da ist mit C-Strings gearbeitet worden. Ich finde die C++ strings auch besser =)
Ich will erstmal diese Grundfunktion zum laufen bringen, und dann werde ich den Code umformen =)
 
Zuletzt bearbeitet:
Hallo,

Blaggi hat gesagt.:
Ich hab doch bereits geschrieben, dass strstr IMMER fehler ausgibt...

Code:
no matching function for call to `strstr(std::string&, const char[5])'
Schon mal dran gedacht, dass das vielleicht an dir liegen könnte und nicht an strstr? ;) strstr arbeitet mit C-Strings, du übergibst hier aber scheinbar einen std::string.

Um zu überprüfen, ob ein String mit einer bestimmten Zeichenkette beginnt, sollte der Vergleich übrigens so aussehen:
if (strstr(szMeinString, "PING ") == szMeinString)

Grüße,
Matthias
 
Hab ich eben herausgefunden, als ich mir genauer die Fehlermeldung angeguckt hab

Ich lasse mir jetzt auch zusätzlich den empfangenen string als C-String ausgeben, mit dem ich dann strstr() nutz =)

Es gibt noch einige kleine Schönheitsfehler, aber ich denke, dass ich die loswerd =)

EDIT: Da mir der Code etwas unübersichtlich ist, hab ich das ganze nochmal in C angefangen.
Ich stoße aber schon jetzt auf ein paar probleme:
Mein Programm crashed bei sprintf:
Code:
sprintf(userstring, "USER %s \"mail\" \"%s\" :%s", data[1], data[2], data[1]);

Deklariet mit
Code:
char userstring[];

EDIT2: Ok, geht jetzt. Ich musste dem Array 20 felder geben...
Aber jetzt finde ich heraus, dass es kein Substr gibt, und ich zu dumm bin sowas selbst zu machen.... rückfall nach C++....

EDIT3:
Ich blick nicht mehr so recht durch, ich hab an allen Ecken Fehler..
Manchmal ist die Ausgabe falsch, z.B:

Code:
NOTICE AUTH :*** Looking up your Hostname
NOTICE AUTH :*** Looking up your ident
NOTICE AUTH :*** found your Hostname
NOTICE AUTH :*** No ident repsone
[sent ping]
No ident response

Ich frage mich, warum der noch ein zweites mal den Fehler ausgibt, aber ohne das "NOTICE AUTH :***"
Ist aber auch nicht immer falsch, ich muss meist nur etwas im Code rumprobieren..
Trozdem gibt es noch andere sehr nervige Fehler...

Er schreibt "[Eingabe] JOIN :#channelname", tut es aber nicht.
Erst wenn ich ca. 2 minuten warte, und der IRC Server den Bot anpinged, joint er #channelnamePING

Wieso hängt der da ein PING dran?

Oder wenn ich den einen invite Sende..
Erstes invite:
[Eingabe] JOIN :#channelname

Alle danach sind normale IRC Invitestrings

Und das, obwohl ich nichtmal eingebaut habe, dass er auf invites joined...

Ich geb euch am besten einfach mal den kompletten code..

Code:
#include <windows.h>
#include <iostream>
#include <string.h>
#include <winsock.h>
#include <process.h>

using namespace std;

// Prototypen
unsigned int VerbindenAnServer(string server, int port);
void AnmeldenAnServer(SOCKET sock, string *zugangsdaten);
void InRaumGehen(SOCKET sock, string *zugangsdaten);
void NachrichtenEmpfangen(void *sock);

// Variablen
string zugangsdaten[4];
bool firstPing = 0;

unsigned int VerbindenAnServer(string server, int port)
{
	char serverip[20];
    SOCKET sock;
	WSADATA wsaData;
    sockaddr_in addr;
		
	if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0)
	    cout << "WSA konnte nicht initialisiert werden.";

    hostent *dns = gethostbyname(server.c_str());

    sprintf(serverip, "%u.%u.%u.%u",
        (unsigned char) dns->h_addr_list[0][0],    (unsigned char) dns->h_addr_list[0][1],
        (unsigned char) dns->h_addr_list[0][2], (unsigned char) dns->h_addr_list[0][3]);

    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(serverip);

    sock = socket(AF_INET, SOCK_STREAM, 0);
    
    if(sock == 0)
    {
        cout << "Socket konnte nicht initialisiert werden";
    }
    if(connect(sock, (sockaddr *) &addr, sizeof(addr)) == -1)
    {
        cout << "Verbindung konnte nicht hergestellt werden";
    }
    
    //char temp[10000];
    /*int x = recv(sock, temp, 10000, 0);
    temp[x] = 0;
    cout<< temp;*/

    return sock;
}

void AnmeldenAnServer(SOCKET sock, string *zugangsdaten)
{
    string nick = "NICK ";
    string user = "USER ";
    //string user;
    
    nick += zugangsdaten[0];
    nick += "\r\n";

    user += zugangsdaten[1];
    user += ' ';
    user += "\"bot@bot.bot\" \"";
    user += zugangsdaten[2];
    user += "\" :";
    user += zugangsdaten[0];
    user += "\r\n";
    
    send(sock, nick.c_str(), nick.length(), 0);
    send(sock, user.c_str(), user.length(), 0);

    /*char temp[10000];
    int x = recv(sock, temp, 10000, 0);
    temp[x] = 0;
    cout<< temp;*/
}

void NachrichtenEmpfangen(void *sock)
{
    char ausgabe[1000];
    int x = 0;
    char* tmp;
    while(1)
    {
        x = recv((SOCKET)sock, ausgabe, 1000, 0);
        
        if(x > 0)
        {            
            string strTemp = ausgabe;
            char* cStringTMP = ausgabe;
                       
            if(strTemp.substr(0, 6) == "PING :")
            {
                string pongStr;
                if(firstPing == 0) 
                {
                    pongStr = "PONG ";
                    pongStr += strTemp.substr(6);
                    firstPing = 1;
                    cout << "[Event] Connected\n";
                } 
                else 
                {
                    pongStr = "PING :";
                    pongStr += zugangsdaten[2];
                }
                pongStr += "\r\n";
                send((SOCKET)sock, pongStr.c_str(), pongStr.length(), 0);
                //cout << pongStr << endl;
                //cout << strTemp;
            }
            else if(strTemp.substr(0, 13) == "NOTICE AUTH :")
            {
                //cout << strTemp << "\r";
            }
            else if((strstr(cStringTMP, "End of /MOTD command.")) && (!strstr(cStringTMP, "PRIVMSG #")))
            {
                string joinString = "JOIN :";
                joinString += zugangsdaten[3];
                cout << "[Eingabe] " << joinString << endl;
                send((SOCKET)sock, joinString.c_str(), joinString.length(), 0);
            }
            else if((strstr(cStringTMP, "JOIN")) && (!strstr(cStringTMP, "PRIVMSG #")))
            {
                cout << "[Join]!" << endl;     
            }
            
            
            ausgabe[x] = 0;
            if(!strstr(strTemp.c_str(), "372")) // DEBUG: MOTD Verstecken damit ich Fehler schneller finde
            {
                cout << ausgabe;
            }
        }
        Sleep(10);
    }
}

int main(int argc, char *argv[])
{
    SOCKET sock;

    // Nick: 0
    // Name: 1
    // Server: 2
    // Raum: 3
    
    if(argc < 5)
    {
        cout << "Usage: bot <nick> <name> <server> <channel>" << endl; 
        cin.get();
        return 1;      
    }
    else
    {
        cout << "Nick: " << argv[1] << "\nName: " << argv[2] << "\nServer: " << argv[3] << "\nChannel: " << argv[4] << "\n\nVerbinde...\n" << endl;
        zugangsdaten[0] = argv[1];
        zugangsdaten[1] = argv[2];
        zugangsdaten[2] = argv[3];
        zugangsdaten[3] = argv[4];
        
        sock = VerbindenAnServer(zugangsdaten[2], 6667);
        AnmeldenAnServer(sock, zugangsdaten);
        _beginthread(NachrichtenEmpfangen, 0, (void *)sock);
    }

    cin.get();
    WSACleanup();
    return 0;
}

Vielleicht könnt ihr das bissl Optimieren, ich krieg das im mom garnich hin =(
 
Zuletzt bearbeitet:
Zurück