ß ersetzen durch "ss"



  • Servus. Wieder meine Klausurvorbereitung. Aufgabe: Alle im Wort vorkommenden ß sollen durch ß ersetzt werden. Hier mein Code:

    void Replace(cconst char* src){
    
    	for(char *pos = strstr(src, "ß"); pos!=NULL; pos = strstr(src, "ß")) 
        { 
            pos[0]= 's'; // Ersetzen eines Zeichens 
    		pos[1] = 's';
    		memmove(pos+3,pos+2,strlen(pos));
    		pos[2] = ' ';         // Verschieben des Rests +1 nach vorn 
        } 	
    }
    

    Es funktioniert soweit. Wenn ich das Übergebe:

    int main(void){ 
       char text1[] = "Faß Faß faß faß"; 
        Replace(text1);
        puts(text1); 
        return 0; 
    }
    

    Wird aus alles "Faß" ein "Fass" außer bei dem letzten. Dort wird das letzte Wort als Fa ausgegeben. Was habe ich falsch gemacht bzw. was muss ich ergänzen?


  • Mod

    Du musst nat. Sorge tragen, dasss auch genug Speicher da ist für den String nach dem Ersetzen.



  • Mit welcher Funktion mache ich den das?


  • Mod

    snboy2010 schrieb:

    Mit welcher Funktion mache ich den das?

    Im Rahmen der gezeigten Vorgabe ist das überhaupt nicht möglich. Das müsste hier der Aufrufer selber machen, also zum Beispiel

    char text1[30] = "Faß Faß faß faß";
    

    Dein Algorithmus ist aber noch falsch. Nimm mal als Eingabe etwas, bei dem auf ein 'ß' kein Leerzeichen folgt.



  • So ich habe jetzt die Funktion um die Vorgegebene Deklaration erweitert. Die Ausgabe soll in dest erfolgen.

    void Replace(char* dest,const char* src, const char* old, const char *new){
    		for(char *pos = strstr(src, old); pos!=NULL; pos = strstr(src, old)) 
        { 
            pos[0]= new[0]; // Ersetzen eines Zeichens 
    		pos[1] = new[1];
    		memmove(pos+3,pos+2,strlen(pos));
    		pos[2] = ' ';
             // Verschieben des Rests +1 nach vorn 
        } 
    	for (int i = 0; src[i] != NULL; i++){
    		dest[i] = src[i];}
    }
    	char old[] = "ß";
    	char new[] = "ss";
    	char dest[100];
    	char text1[30] = "Faß Faß"; 
    	Replace(dest,text1, old, new);
        puts(dest); 
        return 0; 
    }
    

    Als Ausgabe kommt nur Kudel Mudel raus. Aber wenn ich es debugge, sehe ich wie in dest das Ergebnis von src kommt. Was habe ich falsch gemacht?



  • Ok, hat sich erledigt. Musste das hier ändern.
    Von:

    char dest[100];
    

    zu

    char dest[100] = "";
    

    Yeah endlich mal selber irgendwie eine Aufgabe gelöst. Vielleicht schaffe ich ja doch irgendwie die 4 zu schreiben.



  • 'ß' ist doch gar nicht im char-zeichensatz drin, oder?
    Muss man da nicht Unicode oder sowas verwenden?



  • Also es funktioniert. In der Ausgabe wird ß durch ss geändert. Und im Debug fenster sehe ich auch, dass es geändert wird. Als Editor sollen wir Virtual C verwenden.


  • Mod

    Ich sehe mehrere Fehler:
    - Nicht der Aufrufer sollte dafür verantwortlich sein, den Zielstring vernünftig zu terminieren. Das ist Aufgabe deiner Funktion.
    - Du veränderst den Quellstring! Das ist garantiert nicht im Sinne der Aufgabenstellung. Du schreibst auch potentiell über das Ende hinaus, was ganz schlimm ist, denn es ist ja nicht garantiert dass der Quellstring genug Platz für das Ergebnis hat.



  • Hmm, also ich bin schon mal sehr happy, dass ich es bisher mal geschrieben habe. Aber wie hätte ich es den ändern sollen?


  • Mod

    Schreib direkt in den Zielstring, anstatt die Quelle zu manipulieren und dann am Ende zu kopieren.

    Zur allergrößten Not kopier erst die Quelle ins Ziel und verändere dann das Ziel auf die Art und Weise, wie du derzeit die Quelle veränderst. Wobei diese Vorgehensweise ziemlich umständlich wäre, besser wäre es, gleich die richtigen Daten ins Ziel zu schreiben.

    Guck dir noch einmal an, wie Zeichenketten in C funktionieren. Die müssen immer mit '\0' abgeschlossen sein und es ist deine Verantwortung, wenn du eine Zeichenkette erstellst, dass das auch passiert. Hier hingegen überschreibst du die terminierende Null mit einem Leerzeichen, wodurch dann das Ende nicht mehr richtig erfasst werden kann.

    A propos Leerzeichen: Deine Funktion kommt nach wie vor nicht damit zurecht, wenn das 'ß' nicht von einem Leerzeichen gefolgt wird. Probier's mal aus!



  • AAAAAAAAA, maaaaaaan. Dieses scheiß Zeug. Warum mache ich das überhaupt!!!!!!!!!!!!!!!!! Keine Ahnung. Ist jedes mal anders. Kapiere es einfach nicht. Warum muss es immer so kompliziert seien.



  • Also ich habe jetzt das hier fabriziert. Ist bestimmt wieder falsch aber sieht besser aus, als das Original.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void Replace(char* dest, const char* src, const char* old, const char *new);
    
    int main(void){
    	char src[3072] = "Das ist eine faß faß Beute.";;
    	char dest[3072] = "";
    	char old[] = "ß";
    	char new[] = "ss";
    	Replace(dest, src, old, new);
    	puts(dest);
    
    	return 0;
    }
    
    void Replace(char* dest, char* src, const char* old, const char *new){
    	char *origin = src;
    	char *pos = strstr(src, old);
    	while (pos)
    	{
    		strncpy(dest, src, pos - src);
    		dest += pos - src;
    		dest += sprintf(dest, "ss", old);
    		src = pos;
    		src += strlen(old);
    		pos = strstr(src, old);
    		origin = src;
    	}
    	strcpy(dest, origin);
    }
    

    Das Problem ist jetzt, dass die Vorgabe der Deklaration ist, dass char* src als const ist. Wenn ich das const wegnehme, dann läuft es, Wenn ich const lasse kommt ein fehler.

    ICH BITTE UM HILFE(((((((


  • Mod

    Das ist ja auch komplett richtig, dass src ein const char* sein soll. Schließlich sollst du ihn nicht ändern! Wenn der Compiler sich beschwert, dann hat er Recht. Beschwert er sich in Zeile 20? Dann weil natürlich auch jede Kopie von src die const-Auszeichnung haben muss, sonst könnte man ja einfach über diese Hintertür das Original ändern.

    In Zeile 26 hast du statt new das "ss" fest eingebaut.



  • Bitte könnte mir jemand diesen Code korrigieren?



  • Setze doch einfach an den 2 Stellen wo du es vergessen hast noch ein "const" hin?

    void Replace(char* dest, const char* src, const char* old, const char *new){
    

    Beim ersten helfe ich dir.

    // EDIT:

    Mich wundert allerdings dass es läuft, da die Deklaration der Methode mit "const char src*" von der eigentlichen Methodensignatur abweicht.

    PS: "const" kann man auch innerhalb von Methoden für Variablen verwenden.
    PPS: Warum kopierst du überhaupt src noch einmal auf "origin"?

    // Next EDIT:
    Und falls du wirklich nicht selbst auf die Lösung kommst. Schau hier rein IDEONE.


  • Mod

    snboy2010 schrieb:

    Wenn ich const lasse kommt ein fehler.

    Das wollen wir in diesem Forum so gut wie nie wissen.
    Was wir wissen wollen, ist welchen Fehler du bekommst. Und das soll dann bitte auch keine Fehlerbeschreibung sein, sondern 1:1 Zeichen für Zeichen genau das, was der Compiler dazu zu sagen hat.

    Evtl. benutzt du einen C++-Compiler? Dann muss nat. auch pos const char* sein, wenn src es ist.
    Und origin sowieso.



  • Ich habe es auch mal probiert. Ohne Änderung wird es dir nicht helfen, weil bei mir sind Sonderzeichen in UTF8. Bei mir tut es das so.

    Aber falls es euch interessiert:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char *makeSS (char *in)
    {
        char *mem = malloc (strlen(in)+1);  
        if (!mem)
            return 0;
        char *out;
        for (out = mem; *in; in++)
        {
            if (*in == -61 && *(in+1) == -97)  // entspricht: if (*in == 'ß')
            {
                *out++ = 's';
                *out++ = 's';
                in++;  // nur nötig bei UTF8
            }
            else
            {
                *out++ = *in;
            }
        }
        *out = 0;
        return mem;
    }
    
    int main()
    {
        char *out = makeSS ("Faß Faß faß faß");
        puts (out);
        free (out); // speicher wieder freigeben
    }
    


  • snboy2010 schrieb:

    while (pos)
    	{
    		strncpy(dest, src, pos - src);
    		dest += pos - src;
    		dest += sprintf(dest, "ss", old);
    }
    

    Nur Deppen benutzen strncpy.
    Was soll das sprintf hier bewirken?
    Genau - Schrott.

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
    char *strreplace(char *out,const char *in,const char *old,const char *new); 
    
    int main(void){ 
        const char *in = "Das ist eine faß faß Beute.", *old = "ß", *new = "ss";
        char out[1000];
        puts(strreplace(out,in,old,new)); 
        return 0; 
    } 
    
    char *strreplace(char *out,const char *in,const char *old,const char *new){ 
    	strcpy(out,in);
        // Anfänger sollten immer for benutzen, while ist was für Profis 
        for(char *pos = strstr(out, old); pos!=NULL; pos = strstr(out, old)) 
        { 
            memmove(pos+strlen(new),pos+strlen(old),strlen(pos+strlen(old))+1); /* Restverschiebung */
            memcpy(pos,new,strlen(new));
        }
        return out;
    }
    

    http://ideone.com/vbApZD



  • covfefe schrieb:

    char *makeSS (char *in)
    {
        char *mem = malloc (strlen(in)+1);
    ...
    }
    
    int main()
    {
        char *out = makeSS ("Faß Faß faß faß");
        ...
    }
    

    Und was soll dieser Müll?


Anmelden zum Antworten