Character aus String entfernen



  • sega schrieb:

    ...
    Offensichtlich muss ich zwischendurch also aus pointer "richtige" Strings machen.

    Der Zeiger muss auf beschreibbaren Speicher zeigen.

    char a[] = "Write me!";				// Speicher darf beschrieben werden.
    	char b[20] = "Write me!";			// Speicher darf beschrieben werden.
    	char* c = "Write me an crash!";		// Speicher darf nicht ohne weiteres beschrieben werden.
    

    Allerdings solltest du den dritten Parameter für memmove noch einmal überdenken, weil du nämlich übers Zeichnkettenende hinaus auf Speicherplatz zugreifst, der möglicherweise nicht deinem Programm gehört und einen Programmabsturz verursachen kann ( segmentaton fault ).

    char buf[] = "+B+r+o+t+s+p+i+n+n+e+";
    	char* p;
    	while ( ( p = strchr ( buf, '+' ) ) != NULL )
    		memmove ( p, p+1, strlen(buf) - (p-buf));
    	puts ( buf );
    


  • [quote="Big Brother"]

    sega schrieb:

    char buf[] = "+B+r+o+t+s+p+i+n+n+e+";
    	char* p;
    	while ( ( p = strchr ( buf, '+' ) ) != NULL )
    		memmove ( p, p+1, strlen(buf) - (p-buf));
    	puts ( buf );
    

    Warum eigentlich überhaupt so? In der Schleife dauernd memmove, strlen und und strchr aufzurufen, ist nicht gerade effizient.

    char buf[] = "+B+r+o+t+s+p+i+n+n+e+";
    char *dest = buf;
    for ( src=buf; *src ; ++src ){
      if ( *src != '+' )
        *dest++=*src;
    }
    *dest='\0';
    

    Oder so ähnlich.



  • [quote="☠c-hasser&#"]

    Big Brother schrieb:

    sega schrieb:

    char buf[] = "+B+r+o+t+s+p+i+n+n+e+";
    	char* p;
    	while ( ( p = strchr ( buf, '+' ) ) != NULL )
    		memmove ( p, p+1, strlen(buf) - (p-buf));
    	puts ( buf );
    

    Warum eigentlich überhaupt so? In der Schleife dauernd memmove, strlen und und strchr aufzurufen, ist nicht gerade effizient.

    nein, aber es macht einfacher zu verstehen, womit man zu tun hat.



  • ☠c-hasser&# schrieb:

    Warum eigentlich überhaupt so?
    In der Schleife dauernd memmove, strlen und und strchr aufzurufen, ist nicht gerade effizient.

    Naja, hier ging es darum, ein Zeichen zu entfernen.
    Wenn alle gefundenen Zeichen entfernt werden sollen, würde ich es im Prinzip so machen wie du, z.B.

    char buf[] = "+B+r+o+t+s+p+i+n+n+e+";
    	char *dest, *src;
    	char to_find = '+';
    	for ( dest = src = buf; *src; src++ )
    		if ( *src != to_find ) *dest ++= *src;
    	while ( dest != src ) *dest++ = 0;
    


  • Sorry, auch ich hab versucht, ein Programm zu schreiben, und steh völlig auf dem Schlauch, hab ich ein Brett vorm Kopf? Bei strcpy bekommt dieses Programm einen Segmentation fault, ich habe es auch schon mit memcpy und memmove versucht.

    char *one = "Hello World!";
    unsigned long length = strlen(one);
    char *pos = strchr(one, 'W');
    printf("%p\n%p\n", one, pos);
    cout << pos << end;
    pos = strcpy(pos, pos+1);
    cout << "Hello World!" << endl;
    one[length-1] = '\0';
    cout << one;
    


  • 1. wenn du C++ benutzt, dann verwende auch std::string. C mit C++ zu kompilieren ist wie an einem Autorally-Rennen mit einem Dreirad teilzunehmen.
    2. one zeigt auf Read-Only Memory. Du musst one entweder als Array deklarieren oder Speicher dynamisch anfordern.
    3. strcpy erwartet Memory-Bereiche, die sich nicht überlappen. Dafür gibt es man: memmove(3), was in diesem Fall benutzt werden soll.



  • supertux schrieb:

    1. wenn du C++ benutzt, dann verwende auch std::string. C mit C++ zu kompilieren ist wie an einem Autorally-Rennen mit einem Dreirad teilzunehmen.

    Ich habe das zwar mit dem G++ kompiliert, aber da das ja im ANSI C-Forum ist, wollte ich schon die C-Funktionen benutzen. Gibt es mit dem C-Compiler Unterschiede?

    supertux schrieb:

    1. one zeigt auf Read-Only Memory. Du musst one entweder als Array deklarieren oder Speicher dynamisch anfordern.

    Aha, interessant. Werde das gleich mal ausprobieren.

    supertux schrieb:

    1. strcpy erwartet Memory-Bereiche, die sich nicht überlappen. Dafür gibt es man: memmove(3), was in diesem Fall benutzt werden soll.

    Ach ja, daran habe ich auch gedacht, wusste aber nicht mehr, wie rum das Ganze war.



  • So sieht das Ganze dann auch schon deutlich besser aus. Danke! 👍

    char one[] = "Hello World!";
    char *pos = strchr(one, 'W');
    memmove(pos, pos+1, strlen(one) - (unsigned long)(pos - one));
    cout << one;
    


  • wxSkip schrieb:

    supertux schrieb:

    1. wenn du C++ benutzt, dann verwende auch std::string. C mit C++ zu kompilieren ist wie an einem Autorally-Rennen mit einem Dreirad teilzunehmen.

    Ich habe das zwar mit dem G++ kompiliert, aber da das ja im ANSI C-Forum ist, wollte ich schon die C-Funktionen benutzen. Gibt es mit dem C-Compiler Unterschiede?

    Du solltest dich für eine Sprache entscheiden. C oder C++? Du benutzt dort "cout", was ein std::ostream ist - also C++. Allerdings willst du mit C-Strings hantieren, also C-Kram. Was denn nun?



  • Oh, das cout hatte ich nicht bemerkt, das habe ich ja bloß zum Testen verwendet, der Fragesteller will ja C benutzen.



  • wxSkip schrieb:

    supertux schrieb:

    1. wenn du C++ benutzt, dann verwende auch std::string. C mit C++ zu kompilieren ist wie an einem Autorally-Rennen mit einem Dreirad teilzunehmen.

    Ich habe das zwar mit dem G++ kompiliert, aber da das ja im ANSI C-Forum ist, wollte ich schon die C-Funktionen benutzen. Gibt es mit dem C-Compiler Unterschiede?

    natürlich, C ist nicht C++ und C++ ist nicht C. Acuh wenn C++ eine große Kompabilität zu C hat, sit es nicht weise, C und C++ zu mischen, weil die Fehler umso schwer zu finden sind, wenn man Verhalten A erwartet und davon ausgeht, dass A eintritt, aber in Wirklichkeit etwas ganz anders passiert.

    Hier ein Bsp:

    #include <stdio.h>
    int main(void)
    {
        printf("C%s\n", sizeof(1==1) == 1 ? "++" : "");
        return 0; 
    }
    
    $ gcc -otest c.c
    ./test
    C
    $ g++ -otest c.c
    ./test
    C++
    

    Siehe http://david.tribble.com/text/cdiffs.htm



  • Janjan schrieb:

    "char" ist ein einzelnes Zeichen.

    Jetzt kapier ich gar nichts mehr.
    Wie kann ich denn dann den Output aus strchr() (in memmove) weiterverwenden?



  • Schnapp dir dein Buch und schlag das Kapitel über Zeiger nach. Dann lies noch die Dokumentationen zu den einzelnen Befehlen. Wenn du jetzt noch dein Hirn einschaltest und überlegst was du eigentliche machen willst und mit bestimmten Code machst, dann bist du der Lösung schon einen großen Schritt weiter.



  • Janjan schrieb:

    Schnapp dir dein Buch und schlag das Kapitel über Zeiger nach. Dann lies noch die Dokumentationen zu den einzelnen Befehlen. Wenn du jetzt noch dein Hirn einschaltest und überlegst was du eigentliche machen willst und mit bestimmten Code machst, dann bist du der Lösung schon einen großen Schritt weiter.

    Ich schlage im Gegenzug vor, dass ihr mir sagt, in welchem Forum man als Anfänger bessere Hilfe bekommen kann. Die Antworten hier im Forum sind etwas zu fortgeschritten für meinen Geschmack und auf 'RTFM' wäre ich auch selbst gekommen.



  • sega schrieb:

    ...
    Jetzt kapier ich gar nichts mehr.
    Wie kann ich denn dann den Output aus strchr() (in memmove) weiterverwenden?

    Ein char ist kein char*. Die Funktion strchr gibt einen Zeiger auf char, also einen char* zurück.
    Die Funktion memmove erwartet zwei Zeiger und die Anzahl der Bytes, die verschoben werden; der Typ der Zeiger ist jedoch uninteressant (darum sind die Zeigertypen in memmove void*).
    Die Funktion strchr gibt also einen Zeiger zurück, die Funktion memmove will Zeiger haben, alles prima. 🙂



  • strchr() gibt keinen char zurück, sondern einen Zeiger auf einen char.
    Das heißt hinter dem char, dessen Adresse der Zeiger speichert, steht der Rest des Strings. Und damit kannst du was anfangen.

    PS: Ich glaube, wenn man ein paar Hundert Beiträge mehr geschrieben hat als ich, nervt es viele auch ein bisschen, wenn immer die gleichen Fragen zu Zeigern usw. auftauchen. Schließlich steht das alles schon in vielen Büchern geschrieben, warum sollte man sich immer wiederholen?
    Ich persönlich kann dir nur zu einem Buch raten, in anderen Foren wird es auch nicht anders sein, schließlich tritt man einem Forum ja nicht nach Gutmütigkeit oder Geduldigkeit bei, sondern nach Thema.



  • sega schrieb:

    Janjan schrieb:

    Schnapp dir dein Buch und schlag das Kapitel über Zeiger nach. Dann lies noch die Dokumentationen zu den einzelnen Befehlen. Wenn du jetzt noch dein Hirn einschaltest und überlegst was du eigentliche machen willst und mit bestimmten Code machst, dann bist du der Lösung schon einen großen Schritt weiter.

    Ich schlage im Gegenzug vor, dass ihr mir sagt, in welchem Forum man als Anfänger bessere Hilfe bekommen kann. Die Antworten hier im Forum sind etwas zu fortgeschritten für meinen Geschmack und auf 'RTFM' wäre ich auch selbst gekommen.

    Nirgends? Junge, wenn du was gebacken haben willst, musst du schon Eigenleistung zeigen. Was würde dir bringen, wenn man dir alles aufm Silbertablett presentiert? Nichts.

    Was Janjan schrieb klingt sehr harsch aber glaub mir, er hat mit der Sache 100% Recht und wenn du selbst auf RTMF gekommen bist, wieso tust du das denn nicht? erwartet nicht von uns, uns das Lernen zu überlassen. Denken, überlegen, usw. musst du nämlich immer noch selber. Dran führt kein Weg vorbei und wenn du das nicht einsiehst, wirst du früher als später scheitern.



  • Alles klar, ich frage nicht weiter.
    Thread bitte schließen.



  • wieso tust du hier die beleidigte Wurst ab?



  • Lass ihn doch, wahrscheinlich hat er sich das Ganze mit dem Forum anders vorgestellt...


Anmelden zum Antworten