was bedeutet dieser funktionsrumpf (pointer)
-
Erst einmal danke für alle Antworten
@zeh mau
du hast recht, in der tat wird der string, auf den buf zeigt in der funktion geändert. ich habe das jetzt so angepasst wie du es sagtest, habe aber noch immer einen segmentation fault.ich sage euch jetzt mal, was getToken() macht, dann könnt ihr damit mehr anfangen:
Sie nimmt den String, auf den buf zeigt, und scannt ihn in einer for-schleife stellenweise (&buf[x]) nach dem String ab, der als letzter Parameter übergeben wurde. In meinem Beispiel also "XY". Dann bricht er die Schleife ab.
Dann kopiert er alles, was in dem String, auf den buf zeigt, und was VOR dem "XY" steht, in den String, auf den das übergebene "*token" zeigt.
Gleichzeitig wird genau dieser Teil aus dem buf-String gelöscht.
Dies ist ja jetzt eigentlich möglich, weil ich das eben entsprechend zeh mau's tipp verändert habe.Hier die Implementierung ('delimiter' wäre z.B. "XY"):
int getToken(char *token, char *buf, int *buflen, char delimiter[3]) { int i; /* buf is too short to contain token, shortest token is delimiter */ if (*buflen < 2) return -1; /* search buf for token-delimiter */ for (i = 0; i < *buflen -1; i++) { if (strncmp(&buf[i],delimiter,2)!=0) token[i] = buf[i]; else break; } /* if token not followed by delimiter, return error */ if ((strncmp(&buf[i], delimiter,2)!=0)) { token[0] = '\0'; return -1; } /* null-terminate token and remove the found token from buf */ else { token[i] = '\0'; memmove(buf, &buf[i+2], BUFSIZE-(i+2)); *buflen -= i+2; return 1; } }
Was mir beim Test aufgefallen ist:
die Funktion getToken() gibt 1 zurück. (habe ich mir printen lassen)DANACH gibt sie einen segmentation fault ! also irgendwie seltsam ?!
woran könnte es noch liegen?
mein String-Pointer 'token' ist ja jetzt auch keine Konstante, also
sollte er da doch auch reinschreiben können?
Habe ich die Speicheralloziierung davon vielleicht falsch gemacht oder so?danke soweit schon mal
-
int main(void) { char strbuf[] = "hallo"; char * pctoken; int ilaenge; // 4 ilaenge = strlen(strbuf); // abschließendes '\0' vergessen?? pctoken = malloc(sizeof(ilaenge)+1); printf("%d",getToken(pctoken,strbuf,&ilaenge,"XY")); free(pctoken); getchar(); return 0; }
Schau mal, ob du hiermit weiterkommst???
-
funktioniert leider nicht.
noch immer genau das selbe. mein konsolen-output:Übergebener String: hallo Rückgabewert von getToken(): 1 Segmentation fault
wieso returned die funktion 1, aber kriegt danach nen speicherzugriffsfehler?
-
erstmal sorry, ich kann nicht editieren weil ich nicht eingeloggt war...
noch ein paar überlegungen / infos meinerseits:
also erstmal ist mein beispiel vom letzten beitrag schmarrn.
in diesem fall returned sie NICHT '1' sondern '-1', was daran liegt,
dass der String "hallo" eben das Token "XY" nicht enthält.wenn ich aber "halloXY" daraus mache, returned die funktion '1'.
d.h. ja eigentlich, wenn man sich die funktion mal ansieht, dass
sie auch die hilfsfunktion "memmove()" erfolgreich aufruft und den
String verändert.ich denke, es liegt an folgendem Block in der funktion:
/* search buf for token-delimiter */ for (i = 0; i < *buflen -1; i++) { if (strncmp(&buf[i],delimiter,2)!=0) token[i] = buf[i]; else break; }
er scheitert da eventuell mit dem vergleichen, oder mit dem schreiben in token.
das wird ja nicht abgefangen... da passiert halt irgend ein fehler, aber er läuft die schleife durch oder breaked irgendwann und läuft dann weiter.und dann kommt er auch in den folgenden Block, wo alles passt und er '1' zurückgibt.
Aber was für Probleme könnte er mit dem o.g. Code haben? Was könnte da schief laufen?
-
int getToken(char * token, char * buf, int *buflen, char delimiter[3]) { int i; /* buf is too short to contain token, shortest token is delimiter */ if (*buflen < 2) return (-1); /* search buf for token-delimiter */ for (i = 0; i < *buflen - 1; i++) { if ( strncmp(&buf[i],delimiter,2) != 0 ) { token[i] = buf[i]; } else break; } /* if token not followed by delimiter, return error */ if ((strncmp(&buf[i], delimiter,2)!=0)) { token[0] = '\0'; return (-1); } /* null-terminate token and remove the found token from buf */ else { token[i] = buf[i]; token[i+1] = '\0'; // ??? memmove(buf, &buf[i+2], BUFSIZE-(i+2)); *buflen = *buflen - i + 2; return (1); } }
Machst du in memmove alles richtig? &buf[i+2] ist doch jenseits von gut und böse, oder?
-
Nice one
wenn ich die Zeile auskommentiere, dann funktioniert es alles soweit.
Allerdings bleibt dann der ursprüngliche String erhalten.
Es soll aber das heraus"gelöscht" werden, was nach Token geschrieben wird.Deshalb wird alles nach vorne verschoben.
Okay, also es ist so: Ich habe eben diese Funktion schon so fertig gekriegt.
Ich studier das haltEs ist eigentlich SEHR unwahrscheinlich, dass da ein Fehler drin ist.
Könnte es auch sein, dass ich das irgendwie bei der Übergabe berücksichtigen muss, oder denkst du wirklich, es ist schlichtweg ein Fehler in der Funktion, den man nur beseitigen kann, wenn man in der Funktion selbst etwas manipuliert?
Trotzdem danke auf jeden Fall
-
Sag mal an, was BUFSIZE ist.
Kannst du mal gedanklich durchspielen, was passiert, wenn du Hallo übergibst. Wenn dann noch fragen sind, melde dich nochmal.
-
also eigentlich weiss ich nicht , warum dieses memmove() ein problem ist..
Bevor wir aber aneinander vorbeireden:
Dass es mit "hallo" nicht funktioniert weiss ich, das sagte ich ja auch.
aber mit "halloXY" funktioniert es ja auch nicht, solange ich memmove() drinstehen
habe.Ist &buf[i+2] nicht das Null-Terminierungs-Zeichen? Da müsste er doch drauf zugreifen können?!
BUFSIZE ist nicht explizit festgelegt, also nimmt er den Standard-Wert, der in C schon bereitgestellt ist oder?
Weiss auch nicht so genau, welcher Wert das ist...
-
Wenn du BUFSIZE in *buflen abänderst...
char buff[] = "peter12paul12mary"; char token[256] = ""; int bufflen = sizeof(buff); printf ("buff:%s\ntoken:%s\n", buff, token); getToken (token, buff, &bufflen, "12"); printf ("buff:%s\ntoken:%s\n", buff, token); getToken (token, buff, &bufflen, "12"); printf ("buff:%s\ntoken:%s\n", buff, token);
-
hi leprechaun.
hier meine ausgabe, wenn ich es so mache wie du sagtest:
buff:peter12paul12mary token: buff:paul12mary token:peter buff:mary token:paul Segmentation fault
es funktioniert so auch alles perfekt mit meinem programm, nur
dass nach allen ausgaben etc. noch ein segmentation fault da ist.
die funktion macht alles, was sie soll, und es klappt,
aber dann eben noch dieser segmentation fault.hast du eine Ahnung, weshalb ?
danke
-
hdi schrieb:
BUFSIZE ist nicht explizit festgelegt, also nimmt er den Standard-Wert, der in C schon bereitgestellt ist oder?
Weiss auch nicht so genau, welcher Wert das ist...Dann sag doch mal, was BUFSIZE ist, sonst sind das Annahmen und keine Fakten.
-
#include <stdio.h> #include <stdlib.h> int getToken(char *token, char *buf, int *buflen, char delimiter[3]) { int i; /* buf is too short to contain token, shortest token is delimiter */ if (*buflen < 2) return (-1); /* search buf for token-delimiter */ for (i = 0; i < *buflen -1; i++) { if (strncmp(&buf[i],delimiter,2)!=0) { token[i] = buf[i]; } else break; } /* if token not followed by delimiter, return error */ if ((strncmp(&buf[i], delimiter,2)!=0)) { token[0] = '\0'; return (-1); } /* null-terminate token and remove the found token from buf */ else { token[i] = '\0'; memmove(buf, (buf + i + 2), strlen(buf) - strlen(token) + 1); *buflen = strlen(buf); return (1); } } int main(void) { char strbuf[] = "peter12paul12mary"; char * pctoken; int ilaenge; ilaenge = strlen(strbuf); pctoken = calloc(256,sizeof(char)); printf("\nStart\n"); printf ("buff:%s\ntoken:%s\nlaenge:%d\n", strbuf, pctoken,ilaenge); printf("\nDurchlauf 1"); getToken (pctoken, strbuf, &ilaenge, "12"); printf ("\nbuff:%s\ntoken:%s\nlaenge:%d\n", strbuf, pctoken,ilaenge); printf("\nDurchlauf 2"); getToken (pctoken, strbuf, &ilaenge, "12"); printf ("\nbuff:%s\ntoken:%s\nlaenge:%d\n", strbuf, pctoken,ilaenge); free(pctoken); getchar(); return 0; }
:p Zeh Mau :p
-
hey,
okay also bufsize wird von ner headerdatei eingelesen und hat Wert 1024.soll das bedeutet, dass er zuviele bytes schreiben will und deshalb dann auf adressen zugreift, die gar nicht belegt sind?
-
..und dein beispiel mit calloc() habe ich gerade probiert, ändert aber nichts leider.
aber ich habe auch nicht die funktion verändert bei memmove(), da sie sicherlich korrekt ist.
-
hdi-logged out schrieb:
hey,
okay also bufsize wird von ner headerdatei eingelesen und hat Wert 1024.soll das bedeutet, dass er zuviele bytes schreiben will und deshalb dann auf adressen zugreift, die gar nicht belegt sind?
Aha, wieso so spät mit der Lösung??
Wenn ich das richtig interpretiere,memmove schreibt beginnend ab der Adresse von buf 1024 von (buf + i +2) ab.
Na wenn das mal nicht in die Hose geht: Segmentation fault!!!Zeh Mau
-
hdi schrieb:
..und dein beispiel mit calloc() habe ich gerade probiert, ändert aber nichts leider.
aber ich habe auch nicht die funktion verändert bei memmove(), da sie sicherlich korrekt ist.
Ich sage zur Funktion:
, die ist nicht ganz fehlerfrei!!!
-
Meine Ausgabe:
Start
buff:peter12paul12mary
token:
laenge:17Durchlauf 1
buff:paul12mary
token:peter
laenge:10Durchlauf 2
buff:mary
token:paul
laenge:4Zeh Mau
-
hey, okay also die funktion will ich nicht ändern, denn das war ja nur ein test von mir. anscheinend ist sie nicht für so kurze strings gedacht, und deshalb funktioniert halt mein beispiel nicht einwandfrei.
aber ich habe jetzt zumindest dank deiner hilfe verstanden, wie das ganze genau arbeitet.
vielen dank !!bis zum nächten mal
-
Gerne!
Zeh Mau