PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] Ich überschreibe anscheinend meine Variablen..



totycro
30-10-2008, 08:34
Hallo,

Ich schreibe gerade ein Programm in C, das URL-Parameter wie z.B. "key=val&key2=val2" parst. Dazu sage ich gleich, dass es eine Hausübung ist, und das Programm funktioniert auch schon, die Variablen werden richtig geparst, aber irgendwo zwischen parsen und ausgeben geht die Information "verloren".
Laut gdb passiert das ungefähr in parseUrlParameter, eben beim zweiten Aufruf der Funktion. Meines Wissens greift in dieser Funktion aber nichts auf das erste Key-Value Paar zu.

Wenn ich das Programm mit dem obigen Beipspiel füttere, kommt diese Ausgabe:
key: key2; val: ;
key: key2; val: val2;
Also überschreibt anscheinend der zweite Key den ersten, und der erste Value verschwindet irgendwo im Nirvana..

Könnte das jemand, der schon mal mit Speicherverwaltung in C zu tun hatte, das mal kurz überfliegen und mir sagen, wo der Fehler vielleicht genau liegen könnte, bzw. worauf ich beim debuggen noch achten könnte/sollte?

Kompilierbares Minimalbeispiel:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

/* data structure used to store url parameters */

struct UrlParameter {
const char *key;
const char *value;
};

/*
* parseUrlParameter
*
* Parses a string that contains a key-value-pair (e.g. "key=value")
* and returns the result in an UrlParameter structure.
*
* @param param_str: a string containing a key-value-pair
* @return: parse result in an UrlParameter struct
*/
struct UrlParameter *parseUrlParameter(const char *param_str) {
struct UrlParameter *param = (struct UrlParameter*) malloc(sizeof(struct UrlParameter));
char buff[1024];

/* we have to create a local copy,
because strtok(3) requires a writeable string */
(void)strcpy(buff, param_str);

param->key = strtok(buff, "=");
param->value = strtok(NULL, "=");

return param;
}

/*
* Parses an Url Parameter string and returns
* an array of pointers to UrlParameter-structs.
*/
struct UrlParameter ** parseUrl(const char *url) {
struct UrlParameter **retval = (struct UrlParameter**) malloc(sizeof(struct UrlParameter*)*512);

{
const char *param_str;
char *strtok_save;
int cur_param = 0;
char buff[1024];

/* create writable copy for strtok */
strcpy(buff, url);

param_str = strtok_r(buff, "&", &strtok_save);

/* parse first key-value pair and save info */
retval[cur_param++] = parseUrlParameter(param_str);

/* parse remaining key-value pair */
while((param_str = strtok_r(NULL, "&", &strtok_save)) != NULL) {
retval[cur_param++] = parseUrlParameter(param_str);
}

/* mark end of array */
retval[cur_param] = NULL;
}
return retval;
}


int main() {
char * line = "key=val&key2=val2";
struct UrlParameter** data = parseUrl(line);

{
int i = 0;
while(data[i] != NULL) {
printf("key: %s; val: %s;\n", data[i]->key, data[i]->value);
i++;
}
}
return 0;

anda_skoa
30-10-2008, 13:10
strtok gibt einen Pointer auf den Token im übergebenen Array zurück.

D.h. wenn du die Werte unabhängig von deinem lokalen Buffer haben willst, musst du sie mit strcpy bzw strncpy kopieren.

Ciao,
_

totycro
30-10-2008, 14:30
Es funktioniert endlich, vielen Dank für deinen Hinweis! :)