String verdoppeln



  • Hallo folgende Aufgabe:

    1. Schreibt ein Programm, das einen String str_in von der Tastatur einliest und intern einen
    zweiten String str_out doppelter Länge erzeugt und ausgibt, in dem alle Buchstaben von
    str_in verdoppelt sind. Beispiel: str_in = "String", str_out = "SSttrriinngg".

    Und wie folgt hab ich schon angefangen:

    #include <stdio.h>
    
    int main () 
    {
      char eingabe[100],ausgabe[100];
      scanf ("%s",eingabe);
      ausgabe=eingabe,
      printf ("%s\n",ausgabe);
    }
    

    Ich wollte erstmal schauen ob ich das Array einfach so kopieren kann...da gibt es aber schon Probleme....

    Desweiteren wollte ich das folgender maßen realisieren:

    1. Schau dir an welches Zeichen im Array Eingabe an erster Stelle ist.
    2. Kopiere das Zeichen an die erste Stelle des Arrays ausgabe.
    2. Kopiere das Zeichen an die zweite Stelle des Arrays ausgabe.
    3. Schalte das Array Eingabe ein weiter und fange mit 1 an.

    Wäre das gut oder gibt es eine intelliegentere Lösung?

    Danke für die Hilfe.



  • 1. Nimm Zeichen an pos 0.

    2. Kopiere das Zeichen an die Stelle pos mal 2.
    2. Kopiere das Zeichen an die Stelle pos mal 2 + 1.

    3. Schalte pos eins weiter und mache bei 2. weiter.



  • Ich hab es jetzt so gelöst...bin aber nicht ganz zufrieden.

    #include <stdio.h>
    #define G 100
    #define B 200
    
    int main () 
    {
      char eingabe[G] = {0},ausgabe[B] = {0};  
      int i,p;
      i=0;
      p=0;
      scanf ("%s",eingabe);  
      while (i!=G)
      {
        ausgabe[p]=eingabe[i];
        p=p++;
        ausgabe[p]=eingabe[i];
        p=p++;
        i=i++;
      }
      printf ("%s\n",ausgabe);
    }
    

    Er kopiert ja auch die ganzen Nullen mit...wie kann ich die Abbruchbedingung machen das er dann aufhört wenn im Array eine 0 auftaucht?



  • Odatas schrieb:

    p=p++;
        i=i++;
    }
    

    Das ist beides undefiniertes Verhalten, und benutze C/C++ Codetags, dazu sind sie da.



  • Wutz schrieb:

    Odatas schrieb:

    p=p++;
        i=i++;
    }
    

    Das ist beides undefiniertes Verhalten, und benutze C/C++ Codetags, dazu sind sie da.

    Versteh ich nicht...warum ist das undefiniert?

    i=i++;
    

    Sollte doch eigentlich dafür sorgen das i einen höher gezählt wird oder?



  • Odatas schrieb:

    Versteh ich nicht...warum ist das undefiniert?

    i=i++;
    

    Sollte doch eigentlich dafür sorgen das i einen höher gezählt wird oder?

    Nein, denn

    i++;
    

    ist eine Abkuerzung fuer

    i = i + 1;
    

    Also bloss i++ und nicht i = i++ verwenden.

    Zum anderen Problem: Was meinst du mit all den Nullen, die er kopiert?



  • Du kannst vorher mit strlen die Länge bestimmen.
    Oder als Abbruchbedingung nachsehen, ob an der Stelle eingabe[i] ein '\0' ist.
    ⚠ Die erste Null musst du mitkopieren.

    Und nimm mal aussagekräftigere Bezeichnungen. (bei G und B verliert man apätestens in Zeile 13 die Übersicht.)

    i++ alleine sorgt dafür das i weiter gezählt wird. Und zwar nachdem der Wert benutzt wurde.


  • Mod

    #include <stdio.h>
    
    int main ()
    {
      char eingabe[100], ausgabe[200];  
      scanf("%99[^\n]s", eingabe);
    
      char *e = eingabe, *a = ausgabe;
      do 
        {
          *a++ = *e;
          *a++ = *e;
        }
      while (*e++ != 0);
    
      printf ("%s\n",ausgabe);
      return 0;
    }
    


  • Da sitzt jetzt einer vorm Rechner und verteht nur Bahnhof.


  • Mod

    DirkB schrieb:

    Da sitzt jetzt einer vorm Rechner und verteht nur Bahnhof.

    Ja, ich hatte den Thread noch nicht so weit gelesen, dass der Threadersteller Schwierigkeiten mit dem Erhöhen einer Variable um 1 hat. Da ist ein Beispiel mit Ausnutzen der Postfixeigenschaften vielleicht didaktisch nicht ganz angebracht.

    #include <stdio.h>
    
    int main ()
    {
      char eingabe[100], ausgabe[200];  
      scanf("%99[^\n]s", eingabe);  // ALLES lesen, bis \n oder bis 99 Zeichen (+ Nullterminator). So werden auch Zeilen mit Leerzeichen gelesen.
    
      char *e = eingabe, *a = ausgabe;  // e = Anfang von eingabe, a = anfang von ausgabe
      do
        {
          *a = *e;     // In Ausgabe das Zeichen der Eingabe setzen
           a = a + 1;  // Ausgabezeiger eines weiter setzen
          *a = *e;     // In Ausgabe das Zeichen der Eingabe setzen
           a = a + 1;  // Ausgabezeiger eines weiter setzen
        }
      while ((*e != 0)  &&  (e = e + 1));  // Solange das Eingabezeichen nicht 0 ist. Außerdem Eingabezeiger um eines weiter setzen.
    
      printf ("%s\n",ausgabe);
      return 0;
    }
    

    Jetzt ist nur noch die while-Bedingung clever, aber vermutlich fällt ihm das gar nicht auf, warum die clever ist.

    edit: Klammern vergessen. && bindet stärker als =.



  • Na meine Herren wie man hier gleich nieder gemacht wird weil mir wärend den Weihnachtsferien entfallen war das hochzälen einfach nur i++ und nicht i=i++, ist.

    Schon bin ich in der Kategorie dummer Junge und werd als Idiot bezeichnet.... 🙄

    Sry ich bin erst seid 2 Monaten am Programmieren.

    Trozdem möchte ich euch für eure Mühe danken.



  • Odatas schrieb:

    Na meine Herren wie man hier gleich nieder gemacht wird weil mir wärend den Weihnachtsferien entfallen war das hochzälen einfach nur i++ und nicht i=i++, ist.

    Schon bin ich in der Kategorie dummer Junge und werd als Idiot bezeichnet....

    An welcher Stelle wirst Du niedergemacht und wo wirst Du als Idiot bezeichnet?



  • SeppJ schrieb:

    Ja, ich hatte den Thread noch nicht so weit gelesen, dass der Threadersteller Schwierigkeiten mit dem Erhöhen einer Variable um 1 hat. Da ist ein Beispiel mit Ausnutzen der Postfixeigenschaften vielleicht didaktisch nicht ganz angebracht.

    SeppJ schrieb:

    Jetzt ist nur noch die while-Bedingung clever, aber vermutlich fällt ihm das gar nicht auf, warum die clever ist.



  • In deinem ersten Posting stand:

    char eingabe[100],ausgabe[100];
      scanf ("%s",eingabe);
      ausgabe=eingabe,
    

    Daran kann man sehen, dass dir die C-Grundlagen bezüglich Strings fehlen.

    Da Strings mit Zeigern einhergehen, ist der Code von SeppJ mit Zeigern und Postinkrement schon etwas anspruchsvoll.
    So ging es mir zumindest, als ich sowas zum ersten mal gesehen habe.

    Und das undefinierte Verhalten was dein i = i++; betrifft: Es kann so funktionieren wie du dir das dachtes, muss es aber nicht.

    Du wirst hier als Anfänger betrachtet, was du nach eigener Aussage ja auch bist.

    Und als Idiot hast du dich selber bezeichnet.



  • SeppJ schrieb:

    scanf("%99[^\n]s", eingabe);  // ALLES lesen, bis \n oder bis 99 Zeichen (+ Nullterminator). So werden auch Zeilen mit Leerzeichen gelesen.
    

    Das s ist hier falsch. [] ist ein eigener Formatspezifizierer und kein Prefix für s.



  • Odatas schrieb:

    SeppJ schrieb:

    Ja, ich hatte den Thread noch nicht so weit gelesen, dass der Threadersteller Schwierigkeiten mit dem Erhöhen einer Variable um 1 hat. Da ist ein Beispiel mit Ausnutzen der Postfixeigenschaften vielleicht didaktisch nicht ganz angebracht.

    SeppJ schrieb:

    Jetzt ist nur noch die while-Bedingung clever, aber vermutlich fällt ihm das gar nicht auf, warum die clever ist.

    Du bist zu empfindlich!


  • Mod

    Odatas schrieb:

    SeppJ schrieb:

    Ja, ich hatte den Thread noch nicht so weit gelesen, dass der Threadersteller Schwierigkeiten mit dem Erhöhen einer Variable um 1 hat. Da ist ein Beispiel mit Ausnutzen der Postfixeigenschaften vielleicht didaktisch nicht ganz angebracht.

    Nun, verstehst du denn das erste Programm von mir?

    SeppJ schrieb:

    Jetzt ist nur noch die while-Bedingung clever, aber vermutlich fällt ihm das gar nicht auf, warum die clever ist.

    Nun, verstehst du denn, was ich an der while-Bedingung im zweiten Programm mit "clever" meinen könnte?

    Falls du eine oder beide Fragen mit Nein beantwortest, dann war es eine realistische Einschätzung, so wie sie gedacht war. Wieso sollte ich dir schmeicheln, anstatt zu sagen, was dein tatsächlicher Stand ist? Und falls du die Fragen mit Ja beantworten möchtest, dann müsste ich dich schon nach den Antworten fragen, denn die Probleme sind durchaus subtil und es gibt scheinbar richtige Antworten auf die man leicht kommt, die aber eigentlich gar nicht korrekt sind.



  • Ich kann nicht beide mit Ja beantworten aber bei der While Schleife habe ich eine Vermutung.

    Du machst dir zunutze das die beiden Arrays im Speicher direkt hintereinander liegen. Du kopierst die Array Abbruchbedingung noch mit \0. Und wenn dann dein Pointer einmal weiter springt ist er beim 0. Element von dem Ausgabe Array und hört auf.

    Deshalb musst du auch eine Do While schleife machen weil es sonst am Anfang beim 0. Element schon garnicht weiterachen würde. Aber durch die Do bedingung springt er schon auf das 1 Element und das ist Ungleich 0.

    Kann natürlich auch sein dass ich grad totalen Müll erzählt habe 😉

    Wie dem auch sei vielleicht habe ich es einfach zu hart aufgefasst. Du hast mir ja trozdem geholfen und das finde ich nett von dir. Auch wenn mit einem harten Ton 😃


  • Mod

    Odatas schrieb:

    Du machst dir zunutze das die beiden Arrays im Speicher direkt hintereinander liegen.

    Tun sie nicht*. Nutze ich nicht.

    Du kopierst die Array Abbruchbedingung noch mit \0. Und wenn dann dein Pointer einmal weiter springt ist er beim 0. Element von dem Ausgabe Array und hört auf.

    Klingt wirr.

    Deshalb musst du auch eine Do While schleife machen weil es sonst am Anfang beim 0. Element schon garnicht weiterachen würde. Aber durch die Do bedingung springt er schon auf das 1 Element und das ist Ungleich 0.

    Das ist richtig. Du beschreibst, warum ich do...while benutzt habe.

    Du hast aber gar nicht erkannt, was an der Abbruchbedingung selbst etwas besonderes ist und warum da beispielsweise (*e != 0) && (e = e + 1) und nicht etwa (*e != 0) || (e = e + 1) , obwohl das Ergebnis des Ausdrucks doch in beiden Fällen das gleiche wäre. (Zusatzfrage: Warum wäre es das gleiche Ergebnis?)

    *: Naja, nicht ganz richtig. Vermutlich wird schon Code erzeugt, bei dem das so ist. Aber man kann sich auf solche Sachen nicht verlassen, da sie nicht garantiert sind. Mein Code ist ganz portabel.



  • Ich weiß es nicht genau...ich bin auch erst 3 Monate am Programmieren...hab etwas Nachsicht...

    Jedoch dein Post klang trozdem als ob du mich Idiot nennst...

    Du sagtest das ich Probleme dabei hab eine Variable um 1 weiterzuschalten...das ist ja wohl so ziemlich das einfachste was man in c machen kann...und ja ich hab da was in der syntax vergurgt....aber du hast sinnbildlich gesagt:

    Ich wusste nicht das der Typ nichtmal das Einfachste in c beherscht....

    SO klang es auf jeden Fall für mich...Ist ja jetzt auch egal mir wurde geholfen und alles ist gut.

    Dannke


Anmelden zum Antworten