• Diese Seite verwendet Cookies. Indem du diese Website weiterhin nutzt, erklärst du dich mit der Verwendung von Cookies einverstanden. Erfahre mehr

[C] Wort umdrehen

fjl

Eigener Benutzertitel
Themenstarter #1
Guten Morgen Forum,

seit ich vor einigen Tagen (Wochen) mit C anfing, wollte ich ein Programm schreiben, das mir ein beliebiges Wort rückwärts ausgibt. Schön und gut, nach einigem Herumprobieren und suchen bin ich dann auf folgenden Quelltext gestoßen, den ich ein wenig verändert habe:

Code:
/*Wort-troW*/

#include <stdio.h> 

void zeige(char *c) 
{
	char *d = c;
        
	if (*c != '\0')
        {
		zeige (++d);
                printf ("%c",*c);
	}

}

int main (void) 
{
	char wort[21]; 
        
	printf ("\nBitte geben sie ein Wort ein (maximal 20 Buchstaben): ");
	fgets(wort, 21, stdin); 
        zeige(&wort[0]);
        
}
Das Umschreiben bezog sich nur auf den Austausch von scanf() und ein wenig Umformatiererei. Deshalb auch meine Frage: Was passiert da genau? Die main-Funktion macht mir soweit keine Schwierigkeiten, die "zeige"-Funktion allerdings schon. In dem Online-Tutorial (www.pronix.de) bin ich gerade im Kapitel der Zeiger, ziemlich mittig um genau zu sein. Einige klärende Worte würden mir sehr helfen.

MfG fjl

PS: Mein erster Beitrag, und es werden sicher noch einige folgen.
PPS: Auf eine gute Zusammenarbeit ;).
 

mike

Well-Known Member
#2
Hi!
Du liest ein char Array ein und übergibst die Adresse des ersten Buchstaben. Anschließend wird nur mehr der Pointer verschoben und ein char ausgegegben. Das ganze rekursiv ...

mfg
 

fjl

Eigener Benutzertitel
Themenstarter #3
Vielen Dank für die schnelle Antwort. Die Kapitel über Rekursion und Inkrement-, Dekrement-Operatoren werde ich mir nochmals anschauen.

MfG fjl
 

mike

Well-Known Member
#4
Ist vom Prinzip her nicht kompliziert - gleich wie mit dem FIFO Zeuchs. Er ruft die Funktion so lange auf, bis er auf das letzte Zeichen \0 kommt. Danach wird das Ganze wieder verkehrt abgearbeitet - d.h. printf ("%c",*c); wird ausgegeben - vom letzten bis zum ersten Zeichen.
 
#5
Code:
input = "foo\0"

zeige ("f")
  if (*f != '\0')
     d = f++
     zeige ("o")
       if (*f != '\0')
          d = f++
          zeige("o")
            if (*f != '\0')
              d = f++
              zeige('\0')
                if (f != '\0')
                /* Ende der Rekursion, nun wird der Stack abgebaut, und da bleiben nur noch die printf(3) ueber. Die werden ja nun aber rueckwaerts abgearbeitet */
            printf(d) /* o */
       printf(d)  /* o */
  printf(d)  /* f */
 

boesemar

Well-Known Member
#6
Warum kompliziert wenn es auch einfach geht (mit string.h):

#include <string.h>

void zeige(char *c)
{
int i;
for (i=strlen(c)-1;i>=0;i--) {
printf("%c", c);
}
printf("\n");
}

/* for schleift startet mit strlen(c)-1 , da du anfaengst mit 0 zu indizieren */


Wenn du kein string.h nehmen willst, kannst du die string laenge auch so rausfinden:

void zeige(char *c)
{
int last, i;
for (last = 0; c[last] != '\0'; last++);
/* last steht nun auf deinem letzten character */

/* jetzt ruckwarts bis auf null, wie oben */

for (i = last;i>=0;i--) {
printf("%c", c);
}
printf("\n");
}


Viel spass, ansonsten ist alles richtig. Einen pointer auf das erste element auf eine funktion zu uebergeben ist IMO voll in ordnung (zeige(&wort[0]);) .

Bones
 
#7
Hi, willkommen im Forum.

Um es gut zu verstehen empfehle ich dir das ganze in eine iterative Funktion umzuschreiben ;)


edit: ohhhhhhhh, der pöse boesemar hats schon verraten ;)
 

zmieff

Well-Known Member
#9
wilkommen im Forum :)

noch'n tipp:

array ist gleichbedeutend mit &array[0], beides liefert die Adresse des ersten Elements im Array.
 
#10
Iterative Funktionen sind zwar fast immer vorzuziehen, aber es lohnt sich auch mal rekursive Funktionen anzusehen. Gerade Anfaenger haben damit oft Probleme.
 
#12
Also gut, dann wollen wir mal :)
Code:
ruby -e 'puts "Hello World".reverse'
echo -n Hello World|ruby -pe '$_.reverse!'
Wer hat ne gute sh(1) Loesung dafuer?
 
#13
MrFixit hat gesagt.:
Wer hat ne gute sh(1) Loesung dafuer?
Also entweder einfach rev(1) nehmen oder folgendes Script, welches allerdings Unfug liefert, wenn man es mit Patterns fuettert:

Code:
#!/bin/sh

_rv() {
        case "$1" in
        ? | "") echo -n "$1";;
        *) _rv "${1#?}"; echo -n "${1%${1#?}}" ;;
        esac
}

rv() {
        _rv "$@"
        echo
}

rv "$@"
Wer mag, kann das ja mal verbessern.