Strings Buchstaben vertauschen



  • Dann schau dir mal alle Funktionen aus ctype.h an (und kombiniere sie entsprechend).



  • @DirkB
    Mit der Lösung kann ich ja aber nicht das 'en' mit dem 'x' tauschen... 🤔



  • @Th69
    Dankeschön! Die Funktionen werde ich morgen direkt einbauen!



  • @codinglea naja eigentlich wurde ja schon angedeutet, dass man das nicht "mal eben so" macht, oder? aber wenn du es geschafft hast, bist du um eine erfahrung reicher und kannst dich aufgaben widmen, die noch anspruchsvoller sind und noch mehr hin und her und wiederholung haben.😉

    aber eigentlich ist das eine äußere schleife mit einer inneren schleife, einer verzweigung, in der dann auch wieder schleifen sind usw. usf.. das kann man auch ganz toll in funktionen einpacken und schon ist das alles sehr übersichtlich. dafür malt man dann ja auch diese tollen flussdiagramme, weil man das (meistens) so im kopf gar nicht hinbekommt.



  • @Wade1234
    Okay, danke! Ich werde mir morgen mal ein Flussdiagramm erstellen. 🙂


  • Mod

    @codinglea sagte in Strings Buchstaben vertauschen:

    @Wade1234
    Okay, danke! Ich werde mir morgen mal ein Flussdiagramm erstellen. 🙂

    Naja. Programmieren mit Flussdiagrammen ist ziemlich 1980er...
    Mag hier zwar ganz zweckmäßig sein, aber Zeichenketten als char-Arrays ist halt auch nicht ohne Grund aus der Zeit.



  • @SeppJ naja C wurde bei uns an der fh nur noch bei den ingenieuren gelehrt, während die informationstechniker java lernen mussten. das geschah / geschieht bestimmt nicht ohne grund. aber wenn man sich C als programmiersprache aussucht, muss man sich eben mit sowas wie flussdiagrammen abärgern. 😃



  • Es steht ja noch bei der Mini-Kompression da, dass sowohl x->en als auch en->x vertauscht werden sollen. Da kannst du also nicht eine "normale" String-Replace-Funktion nutzen, sondern du musst gleichzeitig beide ersetzen, damit die Vertauschung reversibel bleibt.

    Also in etwa so:

    finde nächstes Vorkommen von x und von en (das ist das strstr), wähle davon das erste
    
    Wenn kein nächstes Vorkommen:
      kopiere den Rest des Strings und returne die Kopie
    kopiere den String bis vor das erste Vorkommen
    wenn x das Vorkommen ist:
      füge en der Kopie hinzu
      gehe 1 Zeichen weiter und ermittle nächstes Vorkommen von x
    sonst:
      füge x der Kopie hinzu
      gege 2 Zeichen weiter und ermittle nächstes Vorkommen von en
    ermittle wieder das nächstdichtere Vorkommen und gehe zum Wenn
    

    So oder so ähnlich könntest du arbeiten. Wie gesagt sicherstellen, dass du genügend Platz für deinen Ausgabestring hast.


  • Mod

    @Wade1234 sagte in Strings Buchstaben vertauschen:

    @SeppJ naja C wurde bei uns an der fh nur noch bei den ingenieuren gelehrt, während die informationstechniker java lernen mussten. das geschah / geschieht bestimmt nicht ohne grund. aber wenn man sich C als programmiersprache aussucht, muss man sich eben mit sowas wie flussdiagrammen abärgern. 😃

    Man kann und sollte auch in C nicht in Ablaufdiagrammen denken. Aber der Threadersteller ist da sowieso noch ganz weit weg von, da erst einmal die Grundlagen her müssen. Daher: Ist ziemlich wurscht, wie er das genau macht. Aber er sollte im Kopf behalten, dass das letzte professionelle Flussdiagramm vor 50 Jahren gezeichnet wurde. Und das obwohl C auch heute noch eine beliebte Sprache ist 🙂



  • Hi!

    vielleicht kannst du ja mal folgendes Beispiel ansehen( Ist ja bald der 11. 11te(hi)
    zuerst der header spawchar.h

    #ifndef SWAPCHAR_INC
    #define SWAPCHAR_INC 1
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <termios.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    int getch();
    void Vorher(char string3[], int lge);
    void cleararray(char array[], int lge);
    int delstrchar(char quelle[], int xpos);
    int strfindstr(char aufgabe[], char gesucht[], int *sbeginn, int *sende);
    void STRITEIL(char *zfolge, char *erge, int beginn, int ende);
    
    #endif
    

    Dann die dazugehörige Datei swapchar.cpp

    #include "swapchar.h"
    
    /// reads from keypress, doesn't echo
    int getch(){
        struct termios oldt, newt;
        int ch;
        tcgetattr( STDIN_FILENO, &oldt );
        newt = oldt;
        newt.c_lflag &= ~( ICANON | ECHO );
        tcsetattr( STDIN_FILENO, TCSANOW, &newt );
        ch = getchar();
        tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
        return ch;
    }
    
    void Vorher(char string3[], int lge)
    {
     printf("Testlaenge: %d\n", lge);                                                 
     printf("Vorher.: %s\n", string3);                                         
     printf("         01234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
     printf("                  |         |         |         |         |         |         |         |\n");
    }  
    
    void cleararray(char array[], int lge)
    {
     int i;
     for(i = 0; i < lge; i++)
      array[i] = 0;	  
    }
    
    // Loescht aus einem c-String an xpos ein einzelnes char 
    // Bei Erfolg Rueckgabewert = 0, sonst -1;
    int delstrchar(char quelle[], int xpos)
    {
     int wlen, i, rewer = -1;
     wlen  = strlen(quelle);
     
    	
     if ((xpos >= 0) && (xpos < wlen))
     for( i = xpos; i < wlen; i++)
      {
       quelle[i] = quelle[i + 1]; 
       rewer = 0;
       //printf("*");
      }	
      
     return rewer; 
    } 
    
    // Bei Erfolg einen Wert != -1
    int strfindstr(char aufgabe[], char gesucht[], int *sbeginn, int *sende)
    {
     int lgegesucht, erge = -1;
     char *pch;
    
     lgegesucht = strlen(gesucht);
    
     //std::cout << "gesucht laenge:  " << lgegesucht << std::endl;	  
       
    
     pch = strstr(aufgabe, gesucht);
      
      if(pch != NULL)
       {
    	erge = pch - aufgabe + 1;
        *sbeginn = erge;
        *sende = erge + lgegesucht - 1;
       }
      
     return erge;
    }
    
    // Erstes Zeichen im String ist 0 drittes 2
    // Beispiel: "Testeversuch" beginn = 4 ende = 6
    // Ergebnis: eve 
    void STRITEIL(char *zfolge, char *erge, int beginn, int ende)
     {
      int laenge, lge = 0;
      
      lge = strlen(zfolge);
      laenge = (ende - beginn) + 1;
      //printf("**beginn %d    ende %d      laenge %d\n", beginn, ende, laenge);
      
      if((beginn >= 0) && (beginn <= ende) && (ende < lge) && (laenge >= 1))
       {
        strncpy( erge, zfolge + beginn, laenge);
       }
     //printf("erge     %s\n", erge);
     }
    
    
    

    Nun die main.cpp:

    
    
    #include "swapchar.h"
    
    void strersatz(char string3[], char gesucht[], char ersatz[], char dummy[], char ergstr3[], int arlen)
    {
     int apos = -1, epos = -1, lge = 0, xpos;
    	
     lge = strlen(string3);   	
    
      xpos = strfindstr(string3, gesucht, &apos, &epos); 
      printf("gefunden apos: %d   bis epos=%d\n", apos, epos);       
      if (xpos != -1)
       {
        cleararray(ergstr3, 200);
    	STRITEIL(string3, ergstr3, 0, (apos -2));
        //printf("1  *ergstr3:  %s\n", ergstr3);  
    	cleararray(dummy, arlen);
    	STRITEIL(string3, dummy, epos, lge -1);
        //printf("**dummy:  %s\n", dummy);  
    	strcat(ergstr3, ersatz);
        //printf("2  *ergstr3:  %s\n", ergstr3);  
    	strcat(ergstr3, dummy);
        //printf("3  *ergstr3:  %s\n", ergstr3);  
        cleararray(dummy, arlen);
       } 
    
    }	
    
    
    int main(int argc, char **argv)
    {
     char string3[200] = {0};
     char ergstr3[200] = {0};
     char dummy[200] = {0};
     char ersatz[200] = {0};
     char gesucht[200] = {0};
     int lge = -1;
     
      getch(); 
      strcpy(string3, "Hallo, diese Nachricht wird ersetzt. Dieser Quelltext gehoert zu den Systemen."); 
      lge = strlen(string3);   
      Vorher(string3, lge);
     
     
     
      strcpy(gesucht, "diese Nachricht"); 
      strcpy(ersatz, "deine Freundin"); 
      printf("gesucht: %s\n", gesucht);  
      printf("ersatz:  %s\n", ersatz);  
      
      strersatz(string3, gesucht, ersatz, dummy, ergstr3, 200);
      printf("Nachher: %s\n\n", ergstr3);  
    
     
      strcpy(string3, ergstr3); 
      lge = strlen(string3);
      Vorher(string3, lge);
      strcpy(gesucht, "wird ersetzt"); 
      strcpy(ersatz, "hat dein ganzes Konto geplündert");
      
      printf("gesucht: %s\n", gesucht);  
      printf("ersatz:  %s\n", ersatz); 
      strersatz(string3, gesucht, ersatz, dummy, ergstr3, 200);
      printf("\nNachher: %s\n\n", ergstr3);  
      
     
       
      strcpy(string3, ergstr3); 
      lge = strlen(string3);
      Vorher(string3, lge);
      strcpy(gesucht, "Quelltext gehoert zu den Systemen"); 
      strcpy(ersatz, "Brauch ist später in der Ehe Usus");
      
      printf("gesucht: %s\n", gesucht);  
      printf("ersatz:  %s\n", ersatz); 
      strersatz(string3, gesucht, ersatz, dummy, ergstr3, 200);
      printf("\nNachher: %s\n\n", ergstr3);   
    
     
       
      
      return 0;
    }
    
    // Zeichen tauschen en&x, er&q,  y&ch, a&e
    // Tauschoptionen für spaeter
    // string3[k]=='x'
    // string3[k]=='er'
    // string3[k]=='q'
    // string3[k]=='y'
    // string3[k]=='ch'
    // string3[k]=='a'
    //string3[k]=='e'   
    
    

    Gibt einen (für die meisten )lustigen Text aus...
    Nix für unguat!



  • @rustyoldguy
    Die getch()-Anweisung am Am Beginn der main.cpp ist da, um den User die Größe des Fensters bequem
    einstellen zu lassen.



  • Schrott - in jeder Hinsicht.
    Liebe Kinder, nicht nachmachen.



  • @codinglea sagte in Strings Buchstaben vertauschen:

    @DirkB
    Mit der Lösung kann ich ja aber nicht das 'en' mit dem 'x' tauschen... 🤔

    wenn du in ein anderes Array kopierst, geht das.

    Die Lösung für Sonderzeichen löschen steht schon da.



  • Die allgemeine Lösung sieht so aus:
    (im Gegensatz zu dem oben Schrott Genannten ist dieser Code strikt ANSI C konform und somit maximal portabel, läuft also auf allen Plattformen (gleich richtig)).
    Die Aufgabenstellung ist allerdings ebenso Schrott, die o.g. Einschränkungen im Fall für ersetzende Strings sind länger als zu ersetzende musst du unbedingt beachten, d.h. du musst selbst für ausreichend Speicher sorgen, wenn du inplace arbeiten willst.
    Ich zeige dir hier, wie man sowas macht, aber nur für deine Spielereien, im professionellen Geschäft macht man sowas natürlich nicht.

    #include <stdio.h>
    #include <string.h>
    
    char *strreplace(char *str,const char *from,const char *to)
    {
    	char *p=str;
    	while( p=strstr(p,from) )
    	{
    		memmove(p+strlen(to),p+strlen(from),strlen(p+strlen(from))+1);
    		memcpy(p,to,strlen(to));
    		p+=strlen(to);
    	}
    	return str;
    }
    
    int main()
    {
    	char x[64000]="hallo ende";
    	puts(strreplace(x,"en","enn"));
    	return 0;
    }
    

    https://ideone.com/wwoSZW



  • Vielen lieben Dank für eure Bemühungen!
    Mit dem Thema habe ich hier ja ganz schön Trubel aufgewirbelt. 😅
    Ich werde nun versuchen mit euren Antworten zu arbeiten. Ich berichte, welche Methode ich genommen habe!



  • @Wutz: strlen(to) und strlen(from) sollten aber einmalig vor der Schleife berechnet werden (sind ja invariabel innerhalb der Funktion).



  • @Wutz
    Die Lösung ist super, allerdings bekomme ich damit nur eine Tauschoption hin. ('en' zu 'x')
    Wie kriege ich zum Beispiel noch das 'x' zum 'en' umgewandelt?
    Wenn das klappt, bekomme ich ich auch die anderen Tauschoptionen hin.


  • Mod

    @codinglea sagte in Strings Buchstaben vertauschen:

    @Wutz
    Die Lösung ist super, allerdings bekomme ich damit nur eine Tauschoption hin. ('en' zu 'x')
    Wie kriege ich zum Beispiel noch das 'x' zum 'en' umgewandelt?
    Wenn das klappt, bekomme ich ich auch die anderen Tauschoptionen hin.

    Das wäre jetzt eigentlich der Teil, wo du selber zur Übung dran solltest. Wutzs Code sucht immer nach dem nächsten Vorkommen des zu Ersetzenden Strings (Zeile 7). Dann schiebt er passend zur Länge des Ersatzstrings umher (9), fügt das Ersatzwort ein (10) und geht um dessen Länge weiter für den nächsten Suchschritt (11->7).

    Wenn du nun mehrere zu suchende Wörter hast, musst du nach allen davon suchen, gucken, welches davon der nächstgelegene Treffer ist, und dann Wutzs Zeilen 9 bis 11 nachmachen, aber mit dem Ersatzwort das zu dem nächstgefundenen Suchwort passt.

    Dazu musst du dir auch überlegen, wie du überhaupt mehrere Such- und Ersatzwörter in die Funktion hinein bekommst. Bei nur zwei Paaren kann man das ja noch mit vier Parametern machen, aber mit jedem weiteren Paar wird nicht nur der Funktionsaufruf länger (und unflexibler), sondern auch der Code verzweigt sich dann in sehr viele Fallunterscheidungen. Wenn du also auch mehr als nur genau ein oder zwei Paare erlauben möchtest, dann wäre es besser, wenn man eine beliebige Anzahl von Paaren als ein Array von Paaren an die Funktion übergeben kann. Der Code ist dann auch nicht viel komplizierter als mit 4 Parametern für 2 Paare (vielleicht sogar ein bisschen einfacher…) und funktioniert dann für alle möglichen Kombinationen (sogar für 0 Paare, wenn du es richtig machst).



  • @codinglea Das Beispiel von Wutz zeigt, wie du Substrings ersetzen kannst, die unterschiedliche Länge haben.

    Du kannst in einer Schleife durch den String gehen und in einem switch (oder if-else-Kette) schauen, was bei den einzelnen Zeichen gemacht werden soll.
    Findest du ein 'e', dann musst du schauen ob das nächste Zeichen ein 'n' ist. Ist das so, ersetzten.
    Findest du ein 'x', dann musst du es durch "en" ersetzen.
    usw..

    Diese Lösung ist zwar nicht universell, führt aber erstmal zum Ziel.

    Wenn du dann weißt, wie man die Strings an die Funktion übergibst, dann kannst du ja umbauen.



  • @DirkB
    Mit switch wird das bei mir nichts...
    ich werde es mit der if-else-Kette ausprobieren.