String verdoppeln
-
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!
-
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
-
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
-
#include <stdio.h> #include <string.h> int main() { char eingabe[100]; char ausgabe[200]; // Da wir jeden Buchstaben verdoppeln wird die Ausgabe im Extremfall doppelt so groß sein wie die Eingabe int i, j, len; scanf("%99[^\n]", eingabe); len = strlen(eingabe) + 1; // Wir nehmen das Terminierungszeichen mit, dann brauchen wir selber keine Terminierung vornehmen for (i = 0, j = 0; i < len; ++i, j += 2) { ausgabe[j] = eingabe[i]; ausgabe[j + 1] = eingabe[i]; } printf("%s", ausgabe); return 0; }
-
SeppJ schrieb:
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?)Das würde mich jetzt auch mal interessieren. Für mich sieht es auf den ersten Blick so aus, als wenn der zweite Ausdruck auch noch zu TRUE ausgewertet wird, wenn der Eingabestring bereits abgearbeitet ist, während der erste Ausdruck richtigerweise FALSE ergibt, wenn das terminierende '\0'-Zeichen kopiert ist ...
-
Ja, es würde mit ODER nicht abbrechen, war doof formuliert. Aber solange es läuft ergeben beide Ausdrücke immer TRUE, egal ob mit && oder ||. Jedoch wird e nicht erhöht, wenn man || benutzt.
-
Alles klar ...
-
Ah ok dann hab ich jetzt auch verstanden.
Wenn die erste Bedingung nicht mehr funzt wird die 2. auch nicht mehr weiter gemacht. Wobei ich sagen muss dass das ein bischen over the top ist.
Ich meine ich kann den Zähler auch in der While Schleife laufen lassen. Hat genau den gleichen effekt und ich würd behaupten es ist auch Fehler unanfälliger...
Und beim Tippen brauche ich weniger Zeichen. Und mehr Rechenenaufwand ist es für den PC auch nicht.
Sieht sehr schön aus und wirkt auch sehr Kompakt...aber im Grunde etwas too much...
Ich lass mich ja gern berichtigen wenn diese Schreibweiße:while (*e != 0) { *a = *e; a = a + 1; *a = *e; a = a + 1; e=e+1 }
Schlechter ist als die:
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.
-
for(e=eingabe;*e!='\0';++e)//Diesen Schleifenkopf erkennt man als //fertiges Idiom: Laufe über den ganzen String. { *a++ = *e;//*a++= erkennt man auch al fertiges Idiom: Schreibe in //einen String wie in einen Stream rein. *a++ = *e; } *a='\0';//Ausgabestring terminieren
-
Odatas schrieb:
Ich lass mich ja gern berichtigen wenn diese Schreibweiße:
while (*e != 0) { *a = *e; a = a + 1; *a = *e; a = a + 1; e=e+1 }
Schlechter ist als die:
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.
Natürlich ist die zweite Schreibweise schlecht. Schließlich ist das die extra umständliche Schreibweise, die ich aus meinem ursprünglichen, kurzen, knackigen
do { *a++ = *e; *a++ = *e; } while (*e++ != 0);
gemacht habe, damit du es verstehst.