XML - Datei v. Musiktiteln auslesen.....



  • Abend.

    Ich habe mein meinem Programm ein mittelschweres Problem.
    Es sollte eine XML-Datei ausgelesen und in einer Strucktur entsprechend abgelegt werden.

    Mein Problem ist nun aber, dass ich immer nur das erste Lied auslesen kann, bzw. per strstr immer am ersten Lied "hängen" bleibe.

    Ich seh den Fehler leider nicht...
    Eventuell finden mehrere Augen das Problem leichter.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define NULL 0
    #define CMAX 80
    
    typedef struct {
       char interpret[CMAX];
       char album[CMAX];
       char titel[CMAX];
       int  tracknr;
    			   } MDB;
    
    int comp_titel(const void *a, const void *b)
    {
       return strcmp(((MDB*)a)->titel, ((MDB*)b)->titel);
    } /* comp_Name() */
    
    int comp_tracknr(const void *a, const void *b)
    {
    	int *pa, *pb;
    	pa = (int*) a;
    	pb = (int*) b;
    
    	if (*pa < *pb)
    	   return -1;
    	else if (*pb > *pa)
    	   return 1;
    	else
           return 0;
    } /* comp_Name() */
    
    int ausgabe( MDB* pmem, int iLen )
    {
    int i;
    
    for (i=0;i<iLen;i++)
       printf("%d:%s - %s\n  %s  %02d \n", i, (pmem+i)->interpret, (pmem+i)->titel, (pmem+i)->album, (pmem+i)->tracknr);
    return 0;
    } /* ausgabe() */
    
    int main()
    {
    
    MDB such,*found, key;
    
    FILE* readfile;
    char *buffer;                       //Zwischenspeicher allokieren
    long size_readfile;
    char *pPos1, *pPos2;			 	//Positionspointer
    int iFor;                       	//Schleifen-Intager
    int iAnz;                           //Anzahl d. Musikdatensätze aus FILE
    int iTmp=0;
    char cTmp[10];
    MDB *pmem;
    
    // Mediadatei öffnen;
    readfile = fopen("mediaDB.xml", "r");				  	// versuche angegebene Datei zu öffnen;
    if (readfile == NULL)
      {
    	printf("\nFEHLER:\n\tDateihandling mit Quelldatei nicht moeglich!\n\tDas Programm wird beendet...\a\n");
    	fclose(readfile);       							// inputfile im Fehlerfall schliessen!
    	exit(1);
      }
    
    fseek(readfile, 0L, SEEK_END);                          // Pointer auf Fileende setzen;
    size_readfile = ftell(readfile);                        // Dateigröße übergeben;
    rewind(readfile);                                       // Pointer wieder auf Anfang;
    
    buffer = malloc(size_readfile * sizeof(char));	// Speicher allokieren
    if (buffer == NULL)
      {
    	printf("\nFEHLER:\n\tdynamische Speicherreservierung 'buffer' fehlgeschlagen!\n\tDas Programm wird beendet...\a\n");
    	fclose(readfile);  				   					// inputfile im Fehlerfall schliessen!
    	free(buffer);                                       // Speicher freigeben;
    	exit(1);
      }
    
    fread(buffer, sizeof(char), size_readfile, readfile);
    
    // Anzahl d. Elemente aus FILE bestimmen;
    pPos1 = strstr(buffer, "<records count=""");
    if (pPos1 == NULL)
      {
    	printf("\nFEHLER:\n\tStrSrt-Start-Countpointer nicht gefunden!\a\n");
    	fclose(readfile);
    	free(buffer);
    	exit(1);
      }
    
    pPos2 = strstr(buffer, """>");
    if (pPos2 == NULL)
      {
    	printf("\nFEHLER:\n\tStrSrt-Ende-Countpointer nicht gefunden!\a\n");
    	fclose(readfile);
    	free(buffer);
    	exit(1);
      }
    
    strncpy(cTmp, (pPos1+16), 8);           //Anzahl def. funktioniert nicht 100%ig, daher fest 8
    
    iAnz = atoi(cTmp);
    printf("\nEs gibt %i Musikeintraege im File.\n", iAnz);
    
    // dyn.Array erstellen;
    
    pmem = malloc(iAnz * sizeof(MDB));
    if (pmem == NULL)
      {
    	printf("\nFEHLER:\n\tdynamische Speicherreservierung 'buffer' fehlgeschlagen!\n\tDas Programm wird beendet...\a\n");
    	fclose(readfile);  				   					// inputfile im Fehlerfall schliessen!
    	free(buffer);
    	free (pmem);                                        // Speicher freigeben;
    	exit(1);
      }
    
    // Just for Fun - Ladebalken
    printf("\nBitte warten - Media-File wird importiert.....\n\n");
    printf("\t\t\t0%-------------------100%\n");
    printf("\t\t\t");
    
    // Inhalt der Mediendatei umkopieren;
    for (iFor = 0; iFor < iAnz; iFor++)
      {
      // Interpret kopieren;
    	pPos1 = strstr((buffer), "<interpret>");
    	if (pPos1 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Startpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	pPos2 = strstr((buffer), "</interpret>");
    	if (pPos2 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Endpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	strncpy((pmem+iFor)->interpret, (pPos1+11), (pPos2-(pPos1+11)));
    
      // Album kopieren;
    	pPos1 = strstr((buffer), "<album>");
    	if (pPos1 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Startpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	pPos2 = strstr((buffer), "</album>");
    	if (pPos2 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Endpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	strncpy((pmem+iFor)->album, (pPos1+7), (pPos2-(pPos1+7)));
    
      // Titel kopieren;
    	pPos1 = strstr((buffer), "<title>");
    	if (pPos1 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Startpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	pPos2 = strstr((buffer), "</title>");
    	if (pPos2 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Endpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	strncpy((pmem+iFor)->titel, (pPos1+7), (pPos2-(pPos1+7)));
    
      // Liedindex kopieren;
    	pPos1 = strstr(buffer, "<tracknr>");
    	if (pPos1 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Startpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	pPos2 = strstr((buffer), "</tracknr>");
    	if (pPos2 == NULL)
    	  {
    		printf("\nFEHLER:\n\tStrSrt-Endpointer nicht gefunden!\a\n");
    		fclose(readfile);
    		free(buffer);
    		exit(1);
    	  }
    	strncpy(cTmp, (pPos1+9), 5);               //Anzahl def. funktioniert nicht 100%ig, daher fest 8
    	(pmem+iFor)->tracknr = atoi(cTmp);
    
      // Zähler f. Ladebalken;
    	if (iFor == ((int)(iTmp+(iAnz*0.04))))
    	  {
    		printf("@");
            iTmp = iFor;
    	  }
      }
    
    printf("\nUnsortiert\n");
    ausgabe(pmem, iAnz);
    
    qsort(pmem,iAnz,sizeof(MDB),comp_titel);
    
    printf("Sortiert\n");
    ausgabe(pmem, iAnz);
    
    strcpy(such.titel,"Piano Concerto no.2, op.18 in c M");
    printf("Suche nach %s. \n",such.titel);
    found = bsearch(such.titel,pmem,iAnz,sizeof(MDB),comp_titel);
    
    if (found == NULL)
       printf("Suche war erfolglos \n");
    else
       printf("Gefunden im Index %i", found -> tracknr);
    
    getch();
    
    free(buffer);
    fclose(readfile);
    return(0);
    } /* main() */
    

    Danke im Voraus!



  • Naja, einen richtigen XML-Parser zu bauen, ist sicher etwas aufwändig.
    Für deine Zwecke scheint es aber wohl eine einfache Stringbearbeitung auch zu tun.
    Zunächst mal würde ich das abschließende '\0' in deinem buffer-String sicherstellen. Das ginge z.B. mit

    buffer = calloc(1,1+size_readfile);
    


  • Andy082 schrieb:

    Ich habe mein meinem Programm ein mittelschweres Problem.
    Es sollte eine XML-Datei ausgelesen und in einer Strucktur entsprechend abgelegt werden.

    Bist du sicher, dass du eine XML als Format verwenden willst? Problem ist, dass du deine Suche mit strstr immer wieder von vorne beginnst, eigentlich müsstest du so etwas wie buffer+=pos1 verwenden. Die Fehlerbehandlung kommentiere ich erst gar nicht.

    XML ist schön und gut, aber ich glaube kaum, dass man es einfach so in der main-Funktion selber parsen kann. Bei dir müsste schon pos2<pos1 sein, wenn deine XML-Datei standardkonform beginnen würde. Das sind aber garantiert nicht alle Fehler, bis du es fehlerfrei und erweiterbar hinbekommen hast, wird noch einige Zeit vergehen.

    Also: Entweder du steigst auf ein anderes Format um (http://en.wikipedia.org/wiki/Configuration_file gibt dir einen Überblick) oder du suchst dir eine Library, die das für dich macht (http://xmlsoft.org/ wäre da nicht schlecht).


Anmelden zum Antworten