[C/C++] Dynamische Liste durchgehen

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Leon, 16. Mai 2009 .

Schlagworte:
  1. 16. Mai 2009
    Dynamische Liste durchgehen

    Hi,

    ich habe mir eine dynamische Liste erstellt mit folgender Struktur:

    Code:
    typedef struct Knoten
    {
     struct Knoten* next;
     void* content;
     int row;
    }Knoten;
    
    typedef struct Liste
    {
     Knoten* first;
     Knoten* last;
     int count;
    }Liste;
    
    Nun habe ich eine Funktion geschrieben mit der ich die Strings der Knoten bearbeite (hier das Zeilenumbruch Zeichen entferne). Jedoch klappt das immer nur beim ersten Listenelement, welches einen Zeilenumbruch enthält, der Rest wird scheinbar ignoriert. Woran kann das liegen?
    Hier mal die Funktion:

    Code:
    void clean(Liste* l)
    {
     /* Nur in 1. Zeile wird korrigiert, danach nicht mehr*/
     
     Knoten* k = l->first;
     int n=0;
     while(k!=NULL)
     {
     if(strchr((k->content),(int) '\n')!=NULL)
     {
     n=0;
     Knoten* neu= (Knoten*) malloc(sizeof(Knoten));
     char* pufferstring=(char*)malloc(strlen(k->content)*sizeof(char));
     strcpy(pufferstring,(char*)k->content);
     char* pch = strtok (pufferstring,"\n");
     while (pch != NULL)
     {
     if(n==0)
     {
     strcpy(k->content,pch);
     n++;
     }
     else if(n==1)
     {
     if(strlen(pch)>3)
     {
     neu->row=k->row+1;
     strcpy(neu->content,pch);
     neu->next=k->next;
     k->next=neu;
     if(neu->next==NULL){l->last=neu;}//Wenn letzte Element -> setze Adresse von neu
     l->count++;
     }
     n++;
     }
     pch = strtok (NULL, " ,.'!?;/");
     }
     free(pufferstring);
     k=neu;
     }
     k=k->next;
     }
    
    
     
  2. 17. Mai 2009
    AW: Dynamische Liste durchgehen

    In der while-Schleife muss eine Bedingung erfüllt werden, bis neu->next einen Zeiger bekommt, das solltest du ändern.
     
  3. 17. Mai 2009
    AW: Dynamische Liste durchgehen

    Hab jetzt mal die 2. while schleife durch folgendes ersetzt:
    Code:
    while (pch != NULL && n<3)
    
    leider ändert sich nichts daran, dass nur der erste String der den kriterien entspricht bearbeitet wird

    -

    Zu der im ersten Post genannten Frage, hat sich eine weitere aufgetan:
    Ich habe mir eine Funktion zum ersetzen eines weiteren Zeichens bzw. einer Zeichenkette geschrieben.
    Wenn ich die Funktion direkt aus der main aufrufe läuft auch alles wunderbar, wenn ich die Funktion jedoch durch eine andere Funktion aufrufen lasse, die wiederum von der main aufgerufen wirde, bekomme ich einen Fehler:

    Woran kann das liegen?
    Hier mal meine Aufrufstruktur:

    main ruft charReplace auf:

    Code:
    void charReplace(Liste* l)
    {
     HyphenLineBreakReplace(l);
    }
    
    Diese ruft HyphenLineBreakReplace auf mit dem Zeiger auf eine Liste.

    Code:
    void HyphenLineBreakReplace(Liste* l)
    {
     Knoten* k = l->first; 
     while(k!=NULL)
     {
     char* pufferstring=(char*)malloc(strlen(k->content)*sizeof(char)); //Speicher besorgen fuer Pufferstring 1
     char* pufferstring1=(char*)malloc(strlen(k->content)*sizeof(char)); //Speicher besorgen fuer Pufferstring 2
     char stringchar[2]; //String um ein Zeichenzwischenzuspeichern
     strcpy(pufferstring,(char*)k->content); //Inhalt des Knotens wird in Pufferstring kopiert
     for(int i=0;i<strlen(pufferstring);i++) // Fuer die Laenge des pufferstrings wird folgendes ausgefuehrt
     {
     if(pufferstring[i]!='-')
     {
     stringchar[0]=pufferstring[i];
     strcat(pufferstring1,stringchar);
     }
     else if(strlen(pufferstring)>=i+1)
     {
     if(pufferstring[i+1]=='\n')
     {
     i++;
     }
     }
     }
     strcpy(k->content,pufferstring1);
     k=k->next;
     free(pufferstring);
     free(pufferstring1);
     }
    }
    
    
    Wäre echt toll wenn einer wüsste wie ich das beheben kann, da ich ungern alles in eine Funktion hauen würde.
     
  4. 17. Mai 2009
    AW: Dynamische Liste durchgehen

    OO, ziemlich viele Fehler....

    Ich hab mal deinen zweiten Code mal verbesset, wenn ich mehr Zeit habe mach ich das auch mit dem ersten:

    Code:
    void HyphenLineBreakReplace(Liste* l)
    {
     Knoten* k = l->first; 
     while(k!=NULL)
     {
     char stringchar[2]; //String um ein Zeichenzwischenzuspeichern
     memset(&stringchar, 0, sizeof(stringchar)); [COLOR="DarkGreen"]//Array NULLen, sonst kommen Fehler[/COLOR]
    [COLOR="DarkGreen"]
     //Du musst beim reservieren darauf achten das strlen das letzte Terminierungszeichen nicht mitzählt; deswegen +1[/COLOR]
     char* pufferstring1 = (char*)malloc((strlen(k->content)+1) * sizeof(char)); [COLOR="DarkGreen"]//Speicher besorgen fuer Pufferstring 1[/COLOR]
     char* pufferstring2 = (char*)malloc((strlen(k->content)+1) * sizeof(char)); [COLOR="DarkGreen"]//Speicher besorgen fuer Pufferstring 2[/COLOR]
    [COLOR="DarkGreen"] //Benenne deine Variablen in Kommentaren genau so wie du sie auch deklarierst, sonst kommst du durcheinander[/COLOR]
    
     
     strcpy(pufferstring1, (char*)k->content); //Inhalt des Knotens wird in Pufferstring kopiert
     memset(pufferstring2, 0, strlen(k->content) * sizeof(char)); [COLOR="DarkGreen"]//Speicher NULLen, sonst kommen Fehler[/COLOR]
    
     for(int i=0;i<strlen(pufferstring1);i++) // Fuer die Laenge des pufferstrings wird folgendes ausgefuehrt
     {
     if(pufferstring1[i]!='-')
     {
     stringchar[0] = pufferstring1[i]; 
     strcat(pufferstring2,stringchar);
     }
     else if(strlen(pufferstring1)>=i+1)
     {
     if(pufferstring1[i+1]=='\n')
     {
     i++;
     }
     }
     }
    [COLOR="DarkGreen"]
     // Da der Typ content ebenfalls dynamisch ist kann man einfach so
     // den Wert von pufferstrin2 nicht in k->kontent kopieren[/COLOR]
     free(k->content); [COLOR="DarkGreen"] // Denn Speicher für content freigeben; aus
     // der Liste nehmen da er nicht mehr gebraucht wird[/COLOR]
     k->content = pufferstring2; [COLOR="DarkGreen"]// dem pointer content den pufferstring zuweißen[/COLOR]
    
     k=k->next;
    
     free(pufferstring1);
    
     [COLOR="DarkGreen"]// Der Pufferstring 1 wird nun freigegeben da er nicht mehr gebraucht wird
     // Der Pufferstring 2 wird NICHT freigegeben da er ja weiter in der Liste benutzt
     // wird und erst Freigegeben werden sollte wenn er aus der Liste genommen wird[/COLOR]
     }
    }
    Es ist zwar nicht das Optimalste aber es sollte Funktionieren; beim Code bin ich davon
    ausgegangen das die String die an Knoten->content übergeben werden alle Dynamisch sind.
    Sollte einer der Werte von Content eine Verknüpfung mit einer Konstanten Variable sein,
    wird es dann zu einem Fehler führen wenn der Speicher dieser freigeben werden soll.


    Mfg Rushh0ur
     
  5. 17. Mai 2009
    AW: Dynamische Liste durchgehen

    Vielen Dank, hat mir schon sehr weiter geholfen.
    Da ich für den Mac programmiere und dieser bei Speicherallokierungen pedantischer zu sein scheint,
    haben mir insbesondere deine Tipps mit memset geholfen.
    Falls du dir dann nochmal den ersten Code anschauen könntest wäre ich dir sehr dankbar
     
  6. 18. Mai 2009
    AW: Dynamische Liste durchgehen

    Ich würde dir evtl empfehlen mit einem Vector zu arbeiten. Da hast du auch schon direkt "Knoten" drin... in dem Fall sind das die Iteratoren. Zusätzlich kannst du die einzelnen Elemente noch über einen Index ansprechen. (wie bei arrays)

    Hier ist ein Tutorial dazu. Ist nicht schwer damit zu arbeiten

    http://www.dreamincode.net/forums/showtopic33631.htm

    greez
     
  7. 22. Mai 2009
    AW: Dynamische Liste durchgehen

    Was willste genau im ersten Code erreichen, verstehhe ich nicht ganz?
    Willst du die Knoten nach Zeilenumbrüchen durchsuchen und bei fund für jeweils einen Zeilenumbruch einen extra Knoten erstellen?

    Du durchsuchst ja beim ersten Mal mit "strtok (pufferstring,"\n");" und bei jedem weiteren Mal
    mit "strtok (NULL, " ,.'!?;/");"; also doch nicht für jeden Zeilenumbruch....

    mfg Rushh0ur
     
  8. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.