Strings teilen



  • Hallo,

    Aufgabenstellung, Bsp etc. stehen im Programm als Comments.

    Ich bräuchte paar Tipps, weil ich weis net weiter...

    Und auch net die Lösung einfach herzeigen bitte, weil 1. lerne ich nix dabei und 2. werde ich es net verstehn :D.

    Danke schonmal im voraus :)!

    MfG Jackie

    //Aufgabe: Schreiben Sie ein Programm das Wörter teilt, wenn Doppelbuchstaben //vorkommen.
    
    //Beispiel:
    //String A: Wetter -> Das "ter" dann in nen neuen String rein --> String A: "Wet" und String B: "ter"
    
    #include <stdio.h>
    
    #define MAX_LEN 100
    
    void share(char a[], char b[]);
    
    void share(char a[], char b[])
    {
      int x=0;
    
      if(a[x] == a[x+1])
      {
        //...
      }
    }
    
    int main()
    {
      char a[MAX_LEN]; // Gesamter String
      char b[MAX_LEN]; //In diesem String soll dann die 2. Hälfte des Wortes stehn, wenn ein Doppebuchstaben vorhanden is. Im oberen Bespiel: "ter"
    
      printf("Eingabe(1 Wort):");
      gets(a);
    
      printf("1. Hälfte: %s",a);
      printf("2. Hälfte: %s",b);
    
      return(0);
    }
    


  • Das Finden eines doppelten Buchstabens ließe sich in einer Schleife realisieren, in der du die Zeichen nacheinander durchgehst und das aktuelle Zeichen jeweils mit dem nächsten vergleichst (so wie es in der Funktion share() ja auch schon ansatzweise implementiert ist). Dabei solltest du auf die Feldgrenzen achten und am Ende des Strings (gekennzeichnet mit einem NULL-Zeichen, '\0') die Schleife abbrechen.

    Hast du dann ein doppelt vorkommendes Zeichen gefunden, kannst du den String ab dieser Position (die Indizes der beiden Zeichen hast du ja in der Schleife ermittelt) in ein anderes Array kopieren, z. B. mit strcpy().

    Der Ausgangs-String lässt sich dann einfach abschneiden, indem du an der richtigen Stelle (Position des zweiten doppelt vorkommenden Zeichens) ein '\0' setzt.



  • Da musst du halt noch was schreiben wie du ein Wort absuchst - also von den ersten bis zu den letzten Buchstaben vergleichen.

    Willst du auch so etwas berücksichtigen: Auspuffflamme 😕

    MfG f.-th.



  • strcopy is ja so ne Bibliothek.

    Wir müssen ohne dem auskommen...

    void share(char a[], char b[])
    {
      int x=0;
    
      while(a[x] != '\0')
      {
        if(a[x] == a[x+1])
        {
          a[x]='\0';
          b[i]=a[x+1];
        }
      }
    }
    

    So in etwa?



  • Ich würde erst ein mal den Index zwischenspeichern um ab diesem den restlichen
    String zu kopieren und erst danach an dieser Stelle das '\0' setzen.
    Dies weil du sonst beim Kopieren an erster Stelle von String b zu Anfang ein
    '\0' stehen hast und der string b dann theoretisch leer ist. Denn dort wo du
    in String a das '\0' setzt ist eigentlich der Anfang von String b.

    [EDIT]
    Ich sehe erst jetzt, du überschreibst in String a den letzten Buchstaben.

    Beispiel: String a = "Hallo"

    Dann sieht (wenn du das Kopieren nach dem '\0' anfängst) es nach dem Kopieren
    so aus:

    String a = "Ha"
    String b = "lo"

    es fehlt ein Buchstabe.

    Das heißt eigentlich du setzt das '\0' um einen Index zu früh.
    Dennoch: herausfinden ob doppelbuchstaben, wenn ja Index speichern, dann
    kopieren und dann String a abgrenzen.



  • Jackie007 schrieb:

    strcopy is ja so ne Bibliothek.

    Nicht "so ne" sondern die Standardbibliothek.

    Wir müssen ohne dem auskommen...

    String kopieren ohne die Standardbibliotheksfunktion zum Stringkopieren zu benutzen, typisch für schizophrene Professoren, die zu faul sind, sich andere Aufgabenstellungen auszudenken.

    void share(char a[], char b[])
    {
      int x=0;
    
      while(a[x] != '\0')
      {
        if(a[x] == a[x+1])
        {
          a[x]='\0';
          b[i]=a[x+1];
        }
      }
    }
    
    void share(char a[], char b[])
    {
      int i=0,x=0;
    
      while(a[x] != '\0')
      {
        if(a[x] == a[x+1])
        {
          for( ;a[x+1+i];++i ) b[i]=a[x+1+i]; b[i]=0; return;
        }
      }
    }
    


  • wutz, jetzt hast du ihm die Arbeit abgenommen ^^

    Aber ich geb dir recht, als gäbe es keine sinnvollere Aufgabenstellung wie:

    Schreibe ein Programm welches aus einem Word-File (.docx/.doc) den Inhalt
    ausliest und diesen Sinngemäs nach einem Schema formatiert.

    Schema: Großbuchstaben klein
    Gesammten Text um 5 Stellen einrücken
    etc.

    Wär ja mal ne Aufgabe welche die Funktionen der Standard-Bibliotheken verwendet.

    Ach ja:
    Jackie007 schrieb:
    strcopy is ja so ne Bibliothek.

    Nicht "so ne" sondern die Standardbibliothek. --> Es ist keine Bibliothek, sondern
    eine Funktion aus "der" Standardbibliothek ^^



  • itedvo schrieb:

    wutz, jetzt hast du ihm die Arbeit abgenommen ^^

    Nee hat er nicht: Da scheint mindestens noch ein

    a[x+1]=(char)0;
    

    zu fehlen ...

    Die while-Schleife wäre besser eine for-Schleife, dann hätte man auch das
    x++ nicht vergessen! (Wie soll das denn so laufen ?)

    Die Initialisierung der 2ten for-Schleife ist auch unnötig wacklig: das i gehört da definitiv rein.

    Ausserderdem würde ich noch anraten statt gets() fgets() zu verwenden.



  • Danke an alle!

    1. mache eine while schleife bis ein doppelbuchstabe gefunden wurde.

    2. nach dem beenden der while schleife weißt wo der string zu trennen ist und fuegen an der
    trennstelle ein \0 ein.

    3. kopiere den string a ab der position wo getrennt wurde mit einer weiteren while schleife in b .
    lassen sie den index fuer b erst in der zweiten schleife zählen.

    das habe ich als Lösungsvorschlag von jemanden.

    Aber ich kanns net genau übersetzen.

    Eine while-schleife bis ein Doppelbuchstabe gefunden ist.. und dann den String trennen, wenn ein Doppelbuchstabe kommt:

    while(a[x] != '\0')
      {
        if(a[x] == a[x+1])
        {
          a[x+1]='\0';
        }
        x++;
     }
    

    So in etwa? Oder wäre das ohne If() gemeint?

    Dann die 2. While-Schleife zum Kopieren, soll die in der 1. while drinnen sein, oder draußen?

    while(...)
      {  
          b[i]=a[x];
          i++;
          x++; 
      }
      b[i]='\0';
    

    Ich weis nicht was ich in(..) schreiben könnte...

    a[x] != '\0'
    

    bringt auch nix.., hab ich ja oben schon?

    Was dann?

    Danke im Voraus!



  • Jackie007 schrieb:

    Danke an alle!
    2. nach dem beenden der while schleife weißt wo der string zu trennen ist und fuegen an der
    trennstelle ein \0 ein.
    Aber ich kanns net genau übersetzen.

    Eben nicht, wenn du meinen Post gelesen hättest dann würdest du wissen dass du
    dann einen Buchstaben überschreibst.

    Als korrekte Lösung würde ich (gegen deinen Wunsch es selber zu machen) diese
    hier vorschlagen:

    void share(char a[], char b[]){
    
      int i; // Laufvariable
      int posDB=0; // posDB = Position des Doppelbuchstabens
    
      posDB=GetPosDBfromString(a);
    
      if(posDB>0){
         for(i=posDB; a[i]!='\0'; i++)
             b[i-posDB]=a[i];
    	 b[i-posDB]='\0';
         a[posDB]='\0';
      }
    }
    
    int GetPosDBfromString(char a[]){
    
      int i; // Laufvariable
    
      for(i=0; a[i]!='\0'; i++)
         if(a[i]==a[i+1])
            return i+1;
    
      return 0;
    }
    

    getestet mit Visual Studio 2010 Ultimate.

    Gruß
    ITEDVO



  • Die Lösung von itedvo hat den Nachteil, das zwei Funktionen benötigt werden.

    Habe als Basis die Lösung von Wutz genommen, Der Teufel steck allerdings im Detail ..

    Mit "Bett" funktionierts und mit mehr als 2 gleichen Buchstaben auch.

    Hier die (getestete) VS2010 Version.

    #include "stdafx.h"
    #include "string.h"
    
    #define MAX_LEN 100
    
    //Beispiel: 
    //String A: Wetter -> Das "ter" dann in nen neuen String rein --> String A: "Wet" und String B: "ter" 
    
    void share(char a[], char b[]) 
    { 
      int x, i=0; 
    
      for(x=0; a[x] != '\0'; x++) 
      { 
        if(a[x] == a[x+1]) {  // wenn gleich,
          b[0]   = a[x+1];    // vorher kopieren
    	  a[x+1] = (char)0;   // dann trennen
    	  x+=2;
          for(i=1 ; a[x] != 0; i++, x++ ) 
    		  b[i] = a[x];
    	  x--;                // letztes zurück
        } 
      } 
      b[i] = (char)0;   // b terminieren
    } 
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
      char a[MAX_LEN];  // Original-String 
      char b[MAX_LEN];  // Rest-String soll dann die 2. Hälfte des Wortes stehn, wenn ein Doppebuchstaben vorhanden is. Im oberen Bespiel: "ter" 
    
      strcpy(a, (char *)"Bett");  // hier später Benutzereingabe
    
      share(a, b); 
    
      printf((char *)" a: %s\n b: %s\n", a, b);
    
    	return 0;
    }
    
    /*
    Ergebnis:
     a: Wet
     b: ter
    */
    


  • itedvo schrieb:

    int GetPosDBfromString(char a[]){

    int i; // Laufvariable

    for(i=0; a[i]!='\0'; i++)
    if(a[i]==a[i+1])
    return i+1;

    return 0;
    }
    [/cpp]

    Dabei kann über das letzte Arrayelement hinaus gelesen werden.



  • merano schrieb:

    Die Lösung von itedvo hat den Nachteil, das zwei Funktionen benötigt werden.

    Nachteil?
    Oh Junge...



  • itedvo schrieb:

    getestet mit Visual Studio 2010 Ultimate.

    Mein Visualstudio hat das bemängelt:

    error C3861: "GetPosDBfromString": Bezeichner wurde nicht gefunden.
    

    Da wäre eine Forwarddeklaration notwendig, oder andere Reihenfolge.

    Immerhin ist das Ergebnis (fast) richtig:

    Die bange Frage was passiert, wenn kein Buchstabe doppelt ist?

    Der String b ist dann leider undefiniert, oder hat den Wert vom letzen mal ..



  • Also, es ist klar dass diese beiden Funktionen vor der main-funktion gehören,
    ansonsten fehlt natürlicherweise ein Prototyp, welchen ich natürlicherweise
    nicht angegeben habe, da man so eine kleinigkeit mit sicherheit verlangen kann
    (Wie auch die richtige Reihenfolge der Deklaration)!

    Weiteres habe ich eine 2. Funktion verwendet nicht weil es nicht anders ging,
    sondern der Übersichtshalber.

    @Bugdetector:
    Eine for-Schleife wird so abgearbeitet:

    Guck Hier!

    folglich kann nicht über das letzte Arrayelement hinübergelesen werden!

    [EDIT]:
    @merano:
    Was soll schon damit sein? Grundlegend ist es doch so: Funktionen erfüllen den im Namen genannten Zweck, ob jetzt aber string b leer bleibt oder nicht wird
    nicht in der Funktion bearbeitet. Sprich würd ich sagen dies sollte anderswertig geschehen so zum Beispiel bei der Deklaration des Strings b mit einer
    gleich darauf folgender Initialisierung!

    char b[MAX_S_LENG]={0};
    

    @Bugdetector:
    Wenn jedoch das Wort nur 1 Buchstabe enthält ist es dennoch 2 Elemente groß.
    Folglich wird es wiederum nicht überschritten (da 2. Element == '\0')

    Wenn der String leer ist, sprich undefinierter Inhalt enthalten ist und man
    dies berücksichtigt müsste man natürlicherweise die for-schleife so umbauen:

    for(i=0; a[i]!='\0' && i < MAX_S_LENG; i++)
    


  • Jop, ich danke euch.

    Ich hab mir die ganze Beiträge durchgelesen etc. und dann selber probiert^^.

    Es funktioniert, ja.

    Aber das Problem ist, wenn ich nur "Montag" eingebe, dann ist String a: Montag und String b:Lauter Zeichen-Character.

    Und ein Stack-Arround kommt auch noch.

    Meine Lösung wäre dieses Unterprogramm(oder Funktion)"share" nur auszuführen, wenn ein Doppelbuchstabe vorkommt und wenn nicht dann soll es nicht ausgeführt werden.

    //Aufgabe: Schreiben Sie ein Programm das die Wörter trennt, wenn Doppelbuchstaben vorkommen.
    //
    //Beispiel:
    //String A: Wetter -> Das "ter" dann in nen neuen String rein --> String A: "Wet" und String B: "ter"
    
    #include <stdio.h>
    
    #define MAX_LEN 100
    
    void share(char a[], char b[]);
    
    void share(char a[], char b[])
    {
      int i=0;
      int x=0;
    
      while(a[x] != a[x+1] && a[x] != '\0')
      {
        x++;
      }
      b[i]=a[x+1];
      i++;
      a[x+1]='\0';
    
      x++;
      x++;
    
      while(a[x] != '\0')
      {
    	  b[i]=a[x];
    	  i++;
    	  x++;
      }
      b[i]='\0';  
    } 
    
    int main()
    {
      char a[MAX_LEN]; // Gesamter String
      char b[MAX_LEN];//In diesem String soll dann die 2. Haelfte des Wortes stehn, wenn ein Doppebuchstaben vorhanden ist. Im oberen Bespiel: "ter"
      int x=0;
    
      printf("Eingabe(1 Wort):\n");
      gets(a);
    
      share(a,b);
    
      printf("1. Haelfte: %s\n",a);
      printf("2. Haelfte: %s\n",b);
    
      return(0);
    }
    


  • Wie behandelst du denn den Fall, wenn kein Doppelzeichen vorkommt?

    void share(char a[], char b[])
    {
      int i=0;
      int x=0;
    
      while(a[x] != a[x+1] && a[x] != '\0')
      {
        x++;
      } 
    // Dann ist hier a[x] == '\0'
      b[i]=a[x+1];  
      i++;
      a[x+1]='\0';
    
      x++;
      x++;
    
      while(a[x] != '\0') // Da x schon weiter ist, kannst du lange auf a[x] == '\0' warten!
      {
          b[i]=a[x];
          i++;
          x++;
      }
      b[i]='\0';  // Das musst du auf alle Fälle machen.
    }
    

    Also darfst du nur weitermachen, wenn nach deiner ersten while-Schleif

    ist.



  • Stimmt, danke!

    Aber ich hab jetzt eine andere Frage.

    Ein \0 ist ja das Ende eines Strings wenn jetzt a[x]='\0' was ist dann a[x+1]?

    Das sind bei mir beim debuggen solche komischen Zeichen. Was ist das?

    Ich dachte der String hört nach dem \0 auf?



  • Dahinter befindet sich das Land des undefinierten 😉



  • Jackie007 schrieb:

    Ich dachte der String hört nach dem \0 auf?

    Der String schon.

    Aber dein Array nicht.
    Das hat MAX_LEN Elemente.
    Und Irgendetwas steht da halt drin.


Anmelden zum Antworten