Anzeige:
Ergebnis 1 bis 3 von 3

Thema: [C] Ich überschreibe anscheinend meine Variablen..

  1. #1
    Registrierter Benutzer
    Registriert seit
    21.07.2006
    Beiträge
    46

    [C] Ich überschreibe anscheinend meine Variablen..

    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:
    Code:
    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:
    Code:
    #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;

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    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,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    21.07.2006
    Beiträge
    46
    Es funktioniert endlich, vielen Dank für deinen Hinweis!

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •