verkettete listen - Einlesen aus Datei



  • Hallo,

    Ich bin dabei ein Programm (W32 Konsolenanwendung) zu schreiben bei dem es darum geht eine Artikel Datenbank zu verwalten. Bis jetzt hab ich den größten Teil gut hinbekommen.

    Nur das einlesen aus einer Datei und Speichern auf eine Liste klappt nicht so recht.

    Ich bekomme bei der Ausgabe immer nur das 1. Element aus der Datei, da das 2. angeblich NULL ist. Meine Ausgabe funktion funktioniert ohne Probleme. Da per Hand eingelesene Artikel ordentlich Ausgegeben werden.

    Die "Datenbank" (txt datei) hat folgenden Aufbau:

    1|Auto|Honda|Kleinwagen|kleiner Kleinwagen mit grossen Reifen|304.00|3400.00
    2|Auto|FIAT|Kleinwagen|kleiner Kleinwagen mit kleinen Reifen|234.00|3400.00
    3|Auto|Opel|Transporter|zum transportieren|3040.00|340000.00

    die ladenfunktion:

    int laden(struct artikel** anfang){
    
      FILE *datei;
      char buffer[255];
      int i,x;
      char *Token;
      //char nr1[255];
      //char nr2[255];
      struct artikel *current = NULL; 
      x=0;
      datei = fopen("db.txt", "r"); //Öffnen der Datei  
    
      if(datei==NULL) //fehlerabfrage
      {
            printf("Fehler - Datei nicht vorhanden oder in Benutzung");
            getch();
            return 4;
      } else { 
    
    	  if (*anfang == NULL){
    
    		  *anfang = (struct artikel *)malloc(sizeof(struct artikel));
    		  (*anfang)->next = NULL;
    		  current = *anfang;  //funktion wird mit programmstart ausgeführt
    
    	       while(!feof(datei)) { //datei bis ende durchgehen
    
    		   while(fgets(buffer,255,datei)){
    
    		   buffer[strlen(buffer)-1]='\0';
    
    		   for (Token=strtok(buffer,"|\n\r"),i=0;Token;Token=strtok(NULL,"|\n\r"),i++){  //auslesen bis trennzeichen
    
    			   switch (i){
    		  case 0: current->id=atoi(Token);
                              break;  
                      case 1: strcpy(current->kategorie,Token);
                              break;        
                      case 2: strcpy(current->lieferant,Token);
                              break;    
                      case 3: strcpy(current->kurzbeschreibung,Token);
                              break;      
                      case 4: strcpy(current->langtext,Token);
                              break;
                      case 5: current->ek_preis=atof(Token);
                              break;
                      case 6: current->vk_preis=atof(Token);
                              break;
                             } //switch ende
    
    		   }  //ende for schleife 
    		   if (!feof(datei)){
    		   current = current->next;	
    		   current = (struct artikel *)malloc(sizeof(struct artikel));
    		   }	
    		   current->next = NULL;
    		   } //ende while schleife
    
    		} //ende while eof
    
    	  } //if ende
      } //else ende
    
    } //funktion laden ende
    

    Ich hoffe ihr könnt mir helfen, wenn ihr weiter infos braucht gerne Fragen 🙂



  • ich glaube das gehört eher nach ANSI C!



  • stimmt ... da sollte es auch eigentlich mal hin ... 😞



  • könnte evt. jemand verschieben den beitrag? wäre nett 🙂



  • current = current->next;
    current = (struct artikel *)malloc(sizeof(struct artikel));
    

    macht keinen sinn 🙂
    erst speicher reservieren, dann den zeiger auf den speicher in current->next speichern, dann current = current->next machen 🙂



  • Hey ho ... vielen dank für die Antwort

    wenn ich das jetzt richtig verstanden habe dann meinst du quasi so:

    current->next = (struct artikel *)malloc(sizeof(struct artikel));
    current = current->next;
    

    dann hab ich leider das Problem das er mir zu den normalen Artikeln noch einen zusätlichen Artikel einliest der aber nur eis Sonderzeichen und zahlen besteht.

    so in der art halt:
    -842150451|ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ|-62774385622041925000000000000000000000000000000.000000|-627743856220419250000000000000000000000.000000

    Beim debuggen hab ich gemerkt, das er einmal zu oft in die if bedingung hinein geht, obwohl das datei ende erreicht ist.

    if (!feof(datei)){
    current->next = (struct artikel *)malloc(sizeof(struct artikel));
    current = current->next;
    }

    Evt. habt ihr für dieses Problem ja auch noch eine einfache Lösung 🙂



  • Dieser Thread wurde von Moderator/in CMatt aus dem Forum C# und .NET in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Das EOF-Flag wird erst dann gesetzt, sobald nochmal aus der Datei gelesen wird, d.h. du mußt nach dem Lesen (fgets) abfragen, ob das Dateiende erreicht wurde.



  • Hey vielen Dank 🙂 ... jetzt geht es

    Die fertige Funktion sieht so aus falls mal jemand ein ähnliches Problem hat:

    int laden(struct artikel** anfang){
    
      FILE *datei;
      char buffer[255];
      int i,x;
      char *Token;
      char nr1[255];
      char nr2[255];
      struct artikel *current = NULL; 
      x=0;
      datei = fopen("db.txt", "r"); //Öffnen der Datei  
    
      if(datei==NULL)
      {
            printf("Fehler - Datei nicht vorhanden oder in Benutzung");
            getch();
            return 4;
      } else {
    
    		   while(!feof(datei)) { 
    
    		   while(fgets(buffer,255,datei)){
    
               if (*anfang == NULL){
    
    		   *anfang = (struct artikel *)malloc(sizeof(struct artikel));
    		   (*anfang)->next = NULL;
    		   current = *anfang;
    
    		   } else { //ende if
    
    		   current->next = (struct artikel *)malloc(sizeof(struct artikel));
    		   current = current->next;	
    		   } //ende else
    
    		   buffer[strlen(buffer)-1]='\0';
    
    		   for (Token=strtok(buffer,"|\n\r"),i=0;Token;Token=strtok(NULL,"|\n\r"),i++){ //string holen
    
    			   switch (i){
    			      case 0: current->id=atoi(Token);
                              break;  
                      case 1: strcpy(current->kategorie,Token);
                              break;        
                      case 2: strcpy(current->lieferant,Token);
                              break;    
                      case 3: strcpy(current->kurzbeschreibung,Token);
                              break;      
                      case 4: strcpy(current->langtext,Token);
                              break;
                      case 5: current->ek_preis=atof(Token);
                              break;
                      case 6: current->vk_preis=atof(Token);
                              break;
                             } //switch ende
    
    		   }  //ende for schleife 
    
    		   }
    
    		   current->next = NULL; //ende setzen 
    		   } //ende while schleife
    
    		} //ende while eof
    
    } //funktion laden ende
    

Anmelden zum Antworten