Pointerarithmetik mit strings: Verständnisprobleme.
-
Hallo zusammen,
Ich komme aus dem Skripting Umfeld (Bash/Ksh, Python, ... auch bissle Java)
und bin kein low-level C Crack, deswegen bin ich gerade dabei "ein Gefühl" für Pointerarithmetik in C zu bekommen, speziell was strings angeht.Dazu habe ich mir eine kleine Spielwiese gebastelt in Form eines Testprogramms in C, worin ich einige Standardfunktionen selbst zu implementieren versuche. Bin dabei noch ganz am Anfang, weil wie gesagt, haperts da noch etwas am Verständnis.
Es kompiliert, aber es crashed + coredumped wegen seqfault.
Hier das Programm:
#include <stdlib.h> // returns length of input_string int my_length (char *input_string) { int size; for ( size=0; *input_string++ != '\0'; size++ ); return size; } // returns index of first occurance of mychar in input_string int my_chrindex (char *input_string, char mychar) { int index; for ( index=0; *input_string++ != mychar; index++ ); return index; } // returns input_string[offset:] (python syntax) char *my_stroffset (char *input_string, int offset) { char *string; // first, jump to the offset, then ... while (--offset) *input_string++; // ... start coping from there on until the end of input_string while ( (*string++ = *input_string++) != '\0' ); return string; } int main (void) { // RULER RULER RULER 012345678 char *mystring = "ABCDEFGHI"; char mychar = mystring[ my_length(mystring) / 2]; printf ( "Index of %c in %s is %d.\n", mychar, mystring, my_chrindex(mystring, mychar) ); /* expected output: String starting off first 'E' in "ABCDEFGHI" is "EFGHI". real output: none (seqfault + coredump) */ printf ( "String starting off first \'%c\' in \"%s\" is \"%s\".\n", mychar, mystring, my_stroffset(mystring, my_chrindex(mystring, mychar) ) ); return 0; }
Wie muss das Programm geändert werden, damit der zu erwartende Output zustande kommt?
Danke im Voraus für alle Antworten.
Tschüss.
-
ändere 'my_stroffset' in:
// returns input_string[offset:] (python syntax) char *my_stroffset (char *input_string, int offset) { return input_string + offset; }
-
Hi DerGrosseC,
dein Fehler liegt in der my_stroffset Funktion.
// returns input_string[offset:] (python syntax) char *my_stroffset (char *input_string, int offset) { char *string; // first, jump to the offset, then ... while (--offset) *input_string++; // ... start coping from there on until the end of input_string while ( (*string++ = *input_string++) != '\0' ); return string; }
In Zeile 7 ist der Stern unnötig, bzw. produziert beim Kompilieren eine Warnung:
Warnung: berechneter Wert ist unbenutzt
input_string++ setzt den Zeiger im Array auf das nächste Element.
*input_string dereferenziert den Zeiger.Es reicht folgendes:
while(--offset) input_string++;
Hierbei gehst du aber ein Zeichen zu wenig.
In C macht man das so:
input_string += offset;
Du möchtest in Zeile 10 den restlichen String kopieren.
Um dies zu machen, mußt du vorher Speicherplatz anlegen.char *string;
definiert dir nur einen Zeigen Namens string vom Typ char*.
Diesem Zeiger mußt du nun mit malloc() Speicher zuweisen:
string = malloc(len-offset+1);
Nun kannst du mit:
i=0; while (*input_string) { string[i] = *input_string; ++input_string; ++i; } string[i] = '\0';
den String kopieren.
Wenn du den String nicht mehr brauchst, mußt du den Speicher
mit free() wieder freigeben.Die gesamte Funktion sieht somit wie folgt aus:
char *my_stroffset (char *input_string, int offset) { char *string; int len = my_length(input_string), i=0; input_string += offset; string = malloc(len-offset+1); while (*input_string) { string[i] = *input_string; ++input_string; ++i; } string[i] = '\0'; return string; }
Hier hast du aber bisher keine Überprüfung, ob len > offset ist.
Falls du den Teilstring aber nicht kopieren möchtest, reduziert
sich deine Funktion auf:char *my_stroffset (char *input_string, int offset) { return input_string+offset; }
Plus Bereichskontrollen!
Gruß mcr
EDIT: Das Kopieren kannst du noch verkürzen:
i = 0; while (*input_string) string[i++] = *input_string++; string[i] = '\0';