Nochmal XML-File einlesen



  • Mit fopen gehts, allerdings mag er
    fprintf(stdout, "%s\n", strerror(errno)); nicht.

    Wenn ich das Auslesen des Speichers komplett auskommentiere läuft die Exe komplett durch und hinterlässt auch das 'NO' nicht in der TXT.

    Ansonsten hängt sich die EXE mit Fehler auf.

    Das Einlesen klappt also schon mal folgendermassen:

    FILE *hfile6 = fopen("\\My Flash Disk\\navigation\\licenses\\feature.xml", "rb");
    		 if (!hfile6)
    			{
    			 wcscat(variable, L"NO");
    			}
    		 else
    			{
                       	 fseek(hfile6, 0, SEEK_END);                //get file size
                       	 size_t filesize = ftell(hfile6); //files >4GB?
    	                    char *buffer = (char*)malloc(filesize+1);                //get memory to contain the whole file
                  		 if (!buffer) puts("Buffer ist leer!"); 
                       	 size_t temp;
                  		  if ((temp=fread(buffer, 1, filesize+1, hfile6))!=filesize)
    				{
     //                   		  free(buffer);
                          	 	 fclose(hfile6);
               			 }
    			}
    

    So... nun jetzt geht es ans Auslesen des Buffers... und da hänge ich jetzt...

    Edit sacht dazu: Wenn ich hinter flcose(hfile6); noch ein wcscat(variable, L"YES"); einfüge, dann bekomme ich dies auch im Textfile ausgegeben:

    Sirf|mfd|-|4920320|NO|storage|484737024|480|272|YES
    


  • Öffnen klappt, das ist ja schonmal was. Wie war das nun? Brauchst du die Werte aus einer bestimmten Zeile? Ist diese Zeile immer an der gleichen Position (z.B. Zeile Nr. 3) und die Werte in der Zeile auch?
    Wenn ja, vermindert sich der Aufwand um einiges, z.B. kannst du dann das Parsen der Variablennamen weglassen. Wenn nicht, musst du wohl einen ähnlichen Weg gehen, wie nwp2 in deinem ersten Thread vorgeschlagen hat.

    Für strerror und errno musst du die Header einbinden, errno.h war das glaube ich.



  • Jep, das steht alles in Zeile 4

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE FeatureLicense SYSTEM "feature.dtd">
    
    <FeatureLicense vendor="MEDION" appVersion="5.0" appName="GoPal Navigator" editionName="AE" master="yes" version="1.0" >
    

    Aus dieser Zeile benötige ich nur die Werte von appVersion= und editionName=

    Alles Andere wird nicht benötigt.



  • Da du die Datei nun auch schon im Puffer hast, kannst du appVersion und editionName mit strstr suchen und dich zu den Werten durchhangeln.
    Willst du die Datei nicht komplett einlesen, würde ich so machen wenn es für mich wäre, reicht hier eine einfache Suche nach den Variablenamen:

    #define SMAX 255
    
    long sfind( FILE* fp, char* s ) // Sucht nach der Zeichenkette s in der zum Lesen geöffneten Datei ("rb").
    {
    	int buf[SMAX+1] = {0}, i=0, n = strlen(s);
    	assert ( n <= SMAX );
    	fseek( fp, 0, SEEK_SET );
    	while ( ( buf[i] = fgetc(fp) ) != EOF ) {
    		if ( buf[i] != s[i] || !s[i] ) {
    			i=0;
    			continue;
    		}
    		i++;
    		if ( i==n )
    			return ftell(fp); // Position hinter dem ersten s in der Datei, oder negativer Wert wenn ftell fehlschlägt.
    	}
    	return -1; // Die Zeichenkette s wurde nicht gefunden.
    }
    

    Auch hier musst du dich noch zu den Werten durchackern. SMAX kannst du einen ausreichend großen Wert geben, z.B. 255. Das ist die maximale Anzahl der Zeichen, die ein Variablenname annehmen darf.



  • Hallo Big Brother,

    sorry, aber da krieg ich keinen Kopf und keinen Ar**** dran. Vielleicht sollte ich doch besser mit LEGO spielen... 😡

    Liegt nur an mir, weil ich das nicht schnalle...

    long sfind( FILE* fp, char* s )
    

    da hab ich folgendes Fehlermeldungen zu:
    error #2157: Unrecognized statement.
    error #2001: Syntax error: expected ';' but found 'sfind'.
    warning #2027: Missing prototype for 'sfind'.
    error #2066: Illegal use of type name 'FILE'
    error #2048: Undeclared identifier 'fp'.
    error #2168: Operands of * have incompatible types 'void' and 'int'.
    error #2039: Illegal expression.
    error #2048: Undeclared identifier 's'.

    Kannst Du mir da noch mal bitte nen Schubs in die richtige Richtung geben???



  • Pitter (c) schrieb:

    Kannst Du mir da noch mal bitte nen Schubs in die richtige Richtung geben???

    nimm 'nen fertigen xml-parser, damit ersparst du dir viel arbeit. vielleicht den: http://www.minixml.org/
    🙂



  • Hallo fricky,

    danke für den Tipp, aber das ist nicht das was ich wollte... 😉



  • Pitter (c) schrieb:

    long sfind( FILE* fp, char* s )
    

    da hab ich folgendes Fehlermeldungen zu:
    ....

    Was soll denn die obige Zeile sein, eine Vorwärtsdeklaration? Ein Funktionsaufruf? Deinem Code nach zu urteilen scheinst du einen Aufruf mit einer Deklaratiion zu verwechseln.



  • Hallo Big Brother,

    wenn ich da nur nen Kopf dran kriegen würde...
    Hab mir schon die Finger wund gesucht, wie ich das hinbekommen könnte.

    Wie deklariere ich denn 's' und 'fp'?

    FILE *hfile6 = fopen("\\My Flash Disk\\navigation\\licenses\\feature.xml", "rb");
    	if (!hfile6)
              {
                 wcscat(variable, L"NO");
              }
             else
    	{
     		long sfind( FILE* fp, char* s ); // Sucht nach der Zeichenkette s in der zum Lesen geöffneten Datei ("rb").
    		{
      	 	 int temp[SMAX+1] = {0}, i=0, n = strlen(s);
       	 	assert ( n <= SMAX );
       		 fseek( fp, 0, SEEK_SET );
      	 	 while ( ( temp[i] = fgetc(temp) ) != EOF )
    			 {
           			 if (temp[i] != s[i] || !s[i] )
    				 {
             		 		 i=0;
              		 	continue;
          	 			 }
           			 i++;
           			 if ( i==n )
               			return ftell(fp); // Position hinter dem ersten s in der Datei, oder negativer Wert wenn ftell fehlschlägt.
    				wchar_t hStr6[100];
    				swprintf(hStr6, L"%d", (fp));
    				wcscat(variable, hStr6);
      	 	 	}
                		 wcscat(variable, L"Error");
    		}
    	}
    

    Ich hoffe, Ihr verliert nicht die Geduld mit mir??? 😞



  • Hallo,

    ich habs nun doch noch hinbekommen.

    Vielleicht durch die Brust ins Auge, aber es funktioniert.

    //Get GoPal-Version #######################################
    
              FILE *hfile6 = fopen("\\My Flash Disk\\navigation\\licenses\\feature.xml", "rb");
    	if (!hfile6)
              {
                 wcscat(variable, L"NO");
              }
             else
    	{
    
    		wchar_t hStr6[100];
    		char Str6[100];
    		char appVersion[20];
    		wchar_t hStr7[100];
    		char Str7[100];
    		char editionName[20];
    
    			// look for appVersion###########################
    
    		char buffer[] = "<FeatureLicense vendor=\"MEDION\" appVersion=\"5.0\" appName=\"GoPal Navigator\" editionName=\"AE\" master=\"yes\" version=\"1.0\" >";	
    		char * position = strstr(buffer, "appVersion="); // search in string
    		int appVersionLength = 0;
    		char * temp = position + sizeof("appVersion=");
    		for (appVersionLength = 0; *temp != '"'; temp++)
    			appVersionLength++;
    
    		strncpy(appVersion, position + sizeof("appVersion="), appVersionLength);
    		sprintf(Str6, "%s", appVersion);			//Variable in ASCII
    
    		MultiByteToWideChar(CP_ACP, 0, Str6, strlen(Str6), hStr6, 200);  	//convert from ASCII to WideChar
    
    		wprintf(L"%ls\n", variable); 
    		wcscat(variable, hStr6);
    		wcscat(variable, L" ");
    
    			//look for editionName##########################
    
    		char * position1 = strstr(buffer, "editionName=");
    		int editionNameLength = 0;
    		char * temp1 = position1 + sizeof("editionName=");
    		for (editionNameLength = 0; *temp1 != '"'; temp1++)
    			editionNameLength++;
    
    		strncpy(editionName, position1 + sizeof("editionName="), editionNameLength);
    		sprintf(Str7, "%s", editionName);
    
    		MultiByteToWideChar(CP_ACP, 0, Str7, strlen(Str7), hStr7, 200);  	//  convert from ASCII to WideChar
    
    		wprintf(L"%ls\n", variable); 
    
    		wcscat(variable, hStr7);
       	}
    

    Vielen Dank für Eure Hilfe... mir qualmt der Schädel... 🕶

    Ich wünsche euch Schöne Weihnachten und einen guten Rutsch nach 2010. :xmas1:



  • Zu früh gefreut... 😡

    Das war so nix.

    Bin jetzt einen Schritt weiter, aber hab da mal eine DAU-Frage zu:

    Warum läuft mir das Script immer in wcscat(variable, L"Error")???
    Kann mir das vielleicht jemand erklären??? Büdde... :xmas1:

    wchar_t fp[200];
    char *s = ("appVersion=");
    wchar_t hStr6[100];
    char Str6[200];
    
        FILE *hfile6 = fopen("\\My Flash Disk\\navigation\\licenses\\feature.xml", "rb");
        if (!hfile6)
             	 {
                	 wcscat(variable, L"NO");
             	 }
             else
        		{
            	 long sfind( FILE* fp, char* s ); // Sucht nach der Zeichenkette s in der zum Lesen geöffneten Datei ("rb").
           			{
               		 int temp[SMAX+1] = {0}, i=0, n = strlen(s);
               		 assert ( n <= SMAX );
                		fseek( fp, 0, SEEK_SET );
               		 while ( (temp[i] = fgetc(temp) ) != EOF )
                			{
                       			 if (temp[i] != s[i] || ! s[i] )
                    			 {
                              		 i=0;
                          			 continue;
                     			}
                       			 i++;
                       			 if ( i==n )
                          		 	return ftell(fp); // Position hinter dem ersten s in der Datei, oder negativer Wert wenn ftell fehlschlägt.
    					sprintf(Str6, "%s",fp);
    					MultiByteToWideChar(CP_ACP, 0, Str6, strlen(Str6), variable, 200);
                    			swprintf(fp, L"%d", (hStr6));
                    			wcscat(variable, hStr6);
                 			}
                 		 wcscat(variable, L"Error");
            		}
        		}
    


  • Das Thema Funktionen solltest du dir dringend mal in einem C Buch oder Tutorial angucken(Deklaration, Definition, Rückabewerte, Aufruf, etc).



  • Hallo,
    bin schon seit ein paar Tagen dabei zu lesen und zu testen, aber ich krieg das nicht ans rennen.



  • Wieso baust du dann immer noch Prototypen mitten in den Code? Warum lässt du die Beispielfunktionen von nwp2 und mir nicht Funktionen bleiben, sondern verstreust sie irgendwo im Quellcode? 😕



  • Vielleicht sollte ich es besser dran geben mit diesem Script, oder mir jemanden suchen, der mir das Teil baut...

    Einfache Sachen kriege ich hin, aber das ist mir gerade alles viel zu hoch.... 😞
    Möglicherweise denke ich auch viel zu kompliziert....



  • Big Brother schrieb:

    Wieso baust du dann immer noch Prototypen mitten in den Code? Warum lässt du die Beispielfunktionen von nwp2 und mir nicht Funktionen bleiben, sondern verstreust sie irgendwo im Quellcode? 😕

    Hallo Big Brother,

    ich geb da nicht auf... und hab den "Bretterzaun" verstanden...
    Also hab ich Deine Funktion vor das Hauptprogramm gestellt.

    Im Hauptprogramm öffne ich die XML mit

    //Get GoPal-Version 
    
    wchar_t variable[20];
    wchar_t Str7[200];
    
    FILE* fp;
    
    fp = fopen("\\My Flash Disk\\navigation\\licenses\\feature.xml", "rb");
      if (!fp)
    	{        
    	wcscat(variable, "--");
    	}
    else
     	{
     	int s = sfind  (fp, "appVersion=");
    

    ...und dann??? Dann steh ich schon wieder doof da. 😕



  • Du kannst dich aber auch gern hinsetzen 😃

    Nagut, prüfe den Rückgabewert von sfind. Ist er >= 0, dann wurde die Zeichenkette gefunden und der Dateizeiger zeigt auf das Zeichen hinter der Zeichenkette:

    ....  appVersion="5.0" 
                    ^
    

    Nun wird es Zeit für die nächste Funktion, die dir den Inhalt zwischen den Anführungszeichen
    liefert, also den Inhalt der Variable.
    Hier aber erst noch eine kleine Verbesserung der sfind Funktion, die jetzt ohne
    einen integer Puffer auskommt und prüft, ob fseek/ftell erfolgreich war:

    // Sucht nach der Zeichenkette s in der zum Lesen geöffneten Datei. 
    long sfind( FILE* fp, char* s ) { 
        int c = 0, i=0, n = strlen(s); 
    	long pos = 0;
        if ( 0 != fseek( fp, 0, SEEK_SET ) ) return -1; // fseek Fehler. 
        while ( ( c = fgetc(fp) ) != EOF ) { 
            if ( c != s[i] || !s[i] ) { 
                i=0; 
                continue; 
            } 
            i++; 
            if ( i == n ) {
    			if ( ( pos = ftell(fp) ) >= 0 )
    				return pos; // Zeichenkette gefunden. Dateizeiger zeigt auf die Position hinter dem ersten s.
    			return -1; // ftell Fehler. 
    		}
        } 
        return -1; // Die Zeichenkette s wurde nicht gefunden. 
    }
    

    Hier der Ansatz zum Extrahieren der Variablenwerte:

    // sz dient hier zur Kontrolle der Puffergrenze von buf.
    int get_value ( FILE* fp, char* buf, sizet_t sz )
    {
    	int c = 0, i = 0;
    	while ( ( c = fgetc(fp) ) != EOF ) { 
    	// ...
    	}
    	return 0; // Ok, der Inhalt der Variable ist im Puffer.
    }
    

    Für die Entwicklungsphase ist es vorteilhaft ein separates Projekt mit einer eigenständigen main Funktion und einer Testdatei anzulegen und nicht ständig irgendwelche Zeilen in einem Fremdcode hin und herzuschubsen:

    int eret ( char* e ) {
    	if(e) fprintf(stderr, "%s: %s\n", e, strerror(errno));
    	else puts(strerror(errno));
    	fcloseall();
    	return 1;
    }
    
    #define VARNAME_MAX 255
    
    int main() {
    	char* sa[] = { "appVersion", "editionName", NULL };
    	char buf[VARNAME_MAX+1] = {0};
    	char* fname = "test.txt";
    	FILE* fp = fopen ( fname, "rb" );
    	if ( fp == NULL ) return eret(fname);
    	if ( 0 > sfind ( fp, sa[0] )) return eret("Die Zeichenkette wurde nicht gefunden.");
    	if ( 0 != get_value( fp, buf, sizeof(buf))) return eret("Variable konnte nicht gelesen werden.");
    	fclose(fp);
    	return 0; // Alles oki doki.
    }
    


  • Hallo Big Brother,

    erst mal herzlichen Dank für Deine Hilfe, aber das ist ne Ecke zu hoch für mich... 😮

    Big Brother schrieb:

    Du kannst dich aber auch gern hinsetzen 😃

    mach ich glatt... nutzt aber nix. 😞

    Big Brother schrieb:

    .
    .
    Hier der Ansatz zum Extrahieren der Variablenwerte:

    // sz dient hier zur Kontrolle der Puffergrenze von buf.
    int get_value ( FILE* fp, char* buf, sizet_t sz )
    {
    	int c = 0, i = 0;
    	while ( ( c = fgetc(fp) ) != EOF ) { 
    	// ...
    	}
    	return 0; // Ok, der Inhalt der Variable ist im Puffer.
    }
    

    jouh... spätestens hier hast Du mich an die Grenzen meiner Aufnahmefähigkeit gebracht...

    Big Brother schrieb:

    Für die Entwicklungsphase ist es vorteilhaft ein separates Projekt mit einer eigenständigen main Funktion und einer Testdatei anzulegen und nicht ständig irgendwelche Zeilen in einem Fremdcode hin und herzuschubsen:

    Hab das Projekt kopiert und alles raus geworfen, was ich da nicht benötige. Mit Deinen Fehlerroutinene komm ich nämlich überhaupt nicht klar...

    Sorry...



  • Pitter (c) schrieb:

    Hab das Projekt kopiert und alles raus geworfen, was ich da nicht benötige. Mit Deinen Fehlerroutinene komm ich nämlich überhaupt nicht klar...

    Die Funktion gibt doch nur eine Fehlermeldung aus, schließt alle geöffneten Dateien und gibt den Wert 1 zurück.
    Eine Art Fehlervisualisierung, mehr nicht. Kannst du ja auch weglassen, meistens
    möchte man aber gern sehen, warum oder an welcher Stelle etwas schief läuft.

    Funktion sfind guckt in der Datei nach, ob die gesuchte Variable vorhanden ist.
    Wenn ja, wird die Funktion get_value aufgerufen.
    Insgesamt hast du es bloß mit drei bis vier Funktionen zu tun,
    das kann man doch verdauen, oder?


Anmelden zum Antworten