Eigene rekursive String Funktionen
-
Hey, ich hab da ein kleines Problem.
Ich hab die Aufgabe gestellt bekommen, ein paar der Standard String Funktionen aus der string.h rekursiv und mit Zeigern/Zeigerarithmetik "nachzubilden".
Für string_len und string_cnt hat das auch gut geklappt aber meine string_cat Funktion liefert leider nur "HALLO" zurück.
Ich muss dazusagen, dass ich was das Thema Zeiger angeht noch nicht alles vollständig begriffen hab also kann es gut sein, dass richtig dumme Fehler drin sind aber ich finde sie nicht^^
Wenn mir jemand erklären könnte, was ich falsch gemacht habe (oder mir elementare Tipps geben könnte) wäre ich sehr dankbar!#include <stdio.h> #include <malloc.h> int string_len(char *str) { if(*str == '\0')return 0; else return 1+string_len(str+sizeof(char)); } int string_cnt(char c, char *str) { if(*str == '\0')return 0; else if(*str == c)return 1+string_cnt(c,str+sizeof(char)); else return string_cnt(c,str+sizeof(char)); } char *cat(char *str1, char *str2, char *ziel) { if(*str1 == '\0' && *str2 == '\0'){ziel += sizeof(char); return ziel;} else if(*str1 == '\0' && *str2 != '\0')return cat(str2,str1,ziel); else if(*str1 != '\0') { ziel = str1; return cat(str1+sizeof(char),str2,ziel+sizeof(char)); } } char *string_cat(char *str1, char *str2) { char *string; string = malloc((string_len(str1)+1 + string_len(str2)+1) *sizeof(char)); string = cat(str1,str2,string); return string; } int main() { printf("Length: %d Anz. Zeichen: %d\n",string_len("HALLOOOOO DU DA!"),string_cnt('D',"HALLOOOOO DU DA")); char *str; str = string_cat("HALLO"," WIE GEHTS DIR?"); printf("%s\n",str); free(str); return 0; }
-
In Zeile 21 willst du nicht die Zeiger einander zuweisen, sondern das, worauf sie zeigen. Die Zuweisung in Zeile 30 darfst du nicht tun weil der Rückgabewert nicht mehr der Anfangsadresse des angeforderten Speicherbereichs entspricht.
Tipp am Rande:
sizeof(char)
ist immer1
.
-
Danke!
Ich denke, darauf wäre ich nicht so bald gekommen.
Das die Zuweisung in Zeile 30 nicht so ganz richtig dachte ich mir schon aber ich war mir auch nicht sicher ^^
Nun klappt es perfekt....und so siehts nun aus(egal ob Kommentar, oder das, was schon steht, beides funktioniert)
#include <stdio.h> #include <malloc.h> int string_len(char *str) { if(*str == '\0')return 0; else return 1+string_len(str+sizeof(char)); } int string_cnt(char c, char *str) { if(*str == '\0')return 0; else if(*str == c)return 1+string_cnt(c,str+sizeof(char)); else return string_cnt(c,str+sizeof(char)); } char *cat(char *str1, char *str2, char *ziel) { /*if(*str1 == '\0' && *str2 == '\0'){ *ziel = '\0'; return ziel;} else if(*str1 == '\0' && *str2 != '\0')return cat(str2,str1,ziel); else if(*str1 != '\0') { *ziel = *str1; return cat(str1+sizeof(char),str2,ziel+sizeof(char)); } */ if(*str1 != '\0') { *ziel = *str1; return cat((str1+sizeof(char)),str2,(ziel+sizeof(char))); } else { if(*str2 != '\0') { *ziel = *str2; return cat(str1,(str2+sizeof(char)),(ziel+sizeof(char))); } else {*ziel='\0';return ziel;} } } char *string_cat(char *str1, char *str2) { char *string; string = malloc((string_len(str1)+1 + string_len(str2)+1) *sizeof(char)); cat(str1,str2,string); return string; } int main() { printf("Length: %d Anz. Zeichen: %d\n",string_len("HALLOOOOO DU DA!"),string_cnt('D',"HALLOOOOO DU DA")); char *str; str = string_cat("HALLOOOO"," WIE GEHTS DIR DA DRAUSSEN?"); printf("%s\n",str); free(str); return 0; }
Und ja, ich weiß, dass sizeof(char) immer 1 zurückgibt aber ich will mir angewöhnen, das trotzdem zuverwenden^^
-
Eigentlich ist es nicht Aufgabe von einem
strcat
, Speicher zu besorgen.
Welchen Sinn hat der Rückgabewert voncat()
?MrMonkey schrieb:
Und ja, ich weiß, dass sizeof(char) immer 1 zurückgibt aber ich will mir angewöhnen, das trotzdem zuverwenden^^
Why?
Kurz und schmerzlos:
#include <stddef.h> #include <stdlib.h> #include <stdio.h> size_t strlen( char const * str ) { return *str ? 1 + strlen( str + 1 ) : 0; } size_t count( char const * str, char ch ) { return *str ? ( *str == ch ) + count( str + 1, ch ) : 0; } void strcpy( char * dst, char const * src ) { *src ? ( *dst = *src ), strcpy( dst + 1, src + 1 ) : ( *dst = 0 ); } void strcat( char * dst, char const * src ) { *dst ? strcat( dst + 1, src ) : strcpy( dst, src ); } int main( void ) { char const empty[] = ""; char const five[] = "12345"; char const haystack[] = "trallala"; char concatenated[ sizeof five + sizeof haystack - 1 ]; strcpy( concatenated, five ); strcat( concatenated, haystack ); printf( "%u %u %u \"%s\"\n", strlen( empty ), strlen( five ), count( haystack, 'r' ), concatenated ); }
-
Okay, ich gebs zu, der Rückgabewert vo cat() hat irgendwie keinen Sinn^^
Ich hab mich nur an die AUfgabe gehalten:
"b) char *string_cat(char *str1,char *str2) bekommt zwei Zeichenketten und hängt
diese aneinander. Hinweis: Diese Funktion muss für die Ergebniszeichenkette ausreichend Speicher
allozieren. Die eigentliche rekursive Verkettung der Zeichenkette sollte durch eine entsprechende
Hilfsfunktion erfolgen, die als Parametern neben den Zeigern auf die zu verkettenden Zeichenketten
einen Zeiger auf die Ergebniszeichenkette erhält.
Die Funktionen aus der Standardbibliothek string.h sollen dabei nicht verwendet werden!"
Deswegen das Speicher besorgen udn der RückgabewertUnd wegen dem sizeof(char) ich meinte mir angewöhnen das hlt immer ordentlich auszuschreiben, bei sizeof(Type). Ich weiß nicht, gibt mir ein Gefühl der Sicherheit
Vo deinem Code versteh ich eigentlich nicht viel(quasi nichts). Ich hab höchstens Vermutungen was dies und jenes bedeutet.
Ich programmiere noch nicht lange in C
-
MrMonkey schrieb:
Ich hab mich nur an die Aufgabe gehalten: [...]
Naja, wenns so gefordert ist ...
MrMonkey schrieb:
Und wegen dem sizeof(char) ich meinte mir angewöhnen das hlt immer ordentlich auszuschreiben, bei sizeof(Type). Ich weiß nicht, gibt mir ein Gefühl der Sicherheit
Zum Weiterzählen brauchst kein
sizeof
, das erledigt die Pointerarithmetik für dich.#include <stdio.h> int main( void ) { int foo[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *bar = foo; bar = bar + sizeof( int ); // rly?? printf( "%d\n", *bar ); }
MrMonkey schrieb:
Von deinem Code versteh ich eigentlich nicht viel(quasi nichts). Ich hab höchstens Vermutungen was dies und jenes bedeutet.
Langform:
size_t strlen( char const * str ) { if( *str ) return 1 + strlen( str + 1 ); return 0; } size_t count( char const * str, char ch ) { if( *str && *str == ch ) return 1 + count( str + 1, ch ); if( *str ) return count( str + 1, ch ); return 0; } void strcpy( char * dst, char const * src ) { if( *src ) { *dst = *src; strcpy( dst + 1, src + 1 ); return; } *dst = 0; } void strcat( char * dst, char const * src ) { if( *dst ) strcat( dst + 1, src ); else strcpy( dst, src ); }
-
Swordfish schrieb:
size_t strlen( char const * str ) { if( *str ) return 1 + strlen( str + 1 ); return 0; } size_t count( char const * str, char ch ) { if( *str && *str == ch ) return 1 + count( str + 1, ch ); if( *str ) return count( str + 1, ch ); return 0; } void strcpy( char * dst, char const * src ) { if( *src ) { *dst = *src; strcpy( dst + 1, src + 1 ); return; } *dst = 0; } void strcat( char * dst, char const * src ) { if( *dst ) strcat( dst + 1, src ); else strcpy( dst, src ); }
Ah okay, jetzt verstehe ich es auch ^^
Nur eine Frage noch, was bedeutet das size_t als Rückgabewert bei den Funktionen strlen und count?
Das hab ich noch nie gesehen/benutzt. Ich brauchte immer nur "Standarddatentypen"
-
size_t
ist ein in<stddef.h>
definierter vorzeichenloser Typ (in der Praxis ein Alias, eintypedef
auf irgendeinenunsigned
Typ), der garantiert groß genug für alle möglichen Objektgrößen in C ist. Diesen Typ hat auch das Ergebnis vonsizeof
.~C++: std::size_t in <cstddef>~
-
MrMonkey schrieb:
Ich hab die Aufgabe gestellt bekommen,
...
Hinweis: Diese Funktion muss für die Ergebniszeichenkette ausreichend Speicher
allozieren.Zeigt die Ahnungslosigkeit deines Aufgabengebers, fachlich unabhängige Aufgaben in einer Funktion zu bündeln. Das ist Anfängerdesign d.h. Schrott.
Lass mich raten, diese deine Aufgabe wurde von einem Professor gestellt?
-
Swordfish schrieb:
size_t
ist ein in<stddef.h>
definierter vorzeichenloser Typ (in der Praxis ein Alias, eintypedef
auf irgendeinenunsigned
Typ), der garantiert groß genug für alle möglichen Objektgrößen in C ist. Diesen Typ hat auch das Ergebnis vonsizeof
.~C++: std::size_t in <cstddef>~
Okay, danke für die Info, ich merks mir
Wutz schrieb:
MrMonkey schrieb:
Ich hab die Aufgabe gestellt bekommen,
...
Hinweis: Diese Funktion muss für die Ergebniszeichenkette ausreichend Speicher
allozieren.Zeigt die Ahnungslosigkeit deines Aufgabengebers, fachlich unabhängige Aufgaben in einer Funktion zu bündeln. Das ist Anfängerdesign d.h. Schrott.
Lass mich raten, diese deine Aufgabe wurde von einem Professor gestellt?...vielleicht
Also ja, wurde sie. 1.Semester Informatik, Programmierung in C
-
Hey,
MrMonkey schrieb:
...vielleicht
Also ja, wurde sie. 1.Semester Informatik, Programmierung in CLass mich raten: GIP bei Prof. W. A.?