Nochmal XML-File einlesen



  • Sorry, aber der alte Fred scheint defekt zu sein, deshalb hier nochmal neu... 😞
    Wenn man das reparieren kann, bitte diesen Beitrag löschen.

    Die Exe läuft ohne Fehlermeldung durch, liest aber die XML nicht aus, da in der hardware.txt ein |NO ausgegeben wird. Ich binb doch wirklich zu blööd, oder übersehe da irgendwas. Kann mir da noch mal bitte einer helfen?

    Hier der Teil-Code:

    //get software-version ME/AE###############################
    
    	HANDLE hFile6 = CreateFile(TEXT("\\My Flash Disk\\navigation\\licenses\feature.xml\0"), GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL, NULL);
    
    	if (hFile6 == INVALID_HANDLE_VALUE)
    		{
    			wcscat(variable, L"NO");
    		}
    	else
    		{
    			// open file in buffer
    
    			char *readFile(const char *filename);
    
     			 //code heavily changed from http://www.cplusplus.com/reference/clibrary/cstdio/fread/
      			  FILE *file = fopen("\\My Flash Disk\\navigation\\licenses\feature.xml", "rb");
       			 if (!file) return 0;
      			 //get file size
       				 fseek(file, 0, SEEK_END);
       				 size_t filesize = ftell(file); //files >4GB?
      				  rewind(file);
       			 //get memory to contain the whole file
       				 char *buffer = (char*)malloc(filesize+1);
       			 if (!buffer) return 0;
       			 //read file
        				size_t temp;
      			  if ((temp=fread(buffer, 1, filesize+1, file))!=filesize){
          				  free(buffer);
           				 fclose(file);
          				  return 0;
    			}
    
    	//look for entries in buffer
    
    				int main();
    				wchar_t hStr6[100];
    				wchar_t hStr7[100];
      				 if (!buffer) exit(-1); //konnte feature.xml nicht lesen!
       				 char *position = strstr(buffer, "appVersion=\"");
       				 int appVersionLength;
       				 char *temp1 = position+sizeof("appVersion=\"");
      				 for (appVersionLength=0; *temp1!='"'; temp++) appVersionLength++;
       				 char *appVersion = (char *)malloc(appVersionLength+1);
       				 strncpy(appVersion, position+sizeof "appVersion=\"", appVersionLength);
    				swprintf(hStr7, L"%d", appVersion);
    				wcscat(variable, hStr7);
    
    				 int editionNameLength;
       				 char *temp2 = position+sizeof("editionName=\"");
      				 for (editionNameLength=0; *temp2!='"'; temp++) editionNameLength++;
       				 char *editionName = (char *)malloc(editionNameLength+1);
       				 strncpy(editionName, position+sizeof "editionName=\"", editionNameLength);
    				swprintf(hStr6, L"%d", editionName);
    				wcscat(variable, hStr6);
       				 free(appVersion);
       				 free(editionName);
    
    	}
    			CloseHandle(hFile6);
    
    	//Write vars to file####################################
    
    				src = _wfopen(L"\\Temp\\hardware.txt", L"a+");
    				fputws(variable, src);
    				fclose(src);
    
    Sleep(3000);
    
    	return 0;
    }
    

    Danke für Eure Hilfe

    Pitter

    Edit: Besser so?



  • main und WinMain in einem Programm 😮 das funzt?
    Wie auch immer - ich schlage vor, mach daraus eine C Minimalversion, ohne den überflüssigen Rummel drum herum. Dann ist die Wahrscheinlichkeit größer, das sich jemand damit beschäftigt.
    Gruß,
    B.B.



  • Hab den Code auf das Wichtige reduziert...

    Ich hoffe das ist besser so?

    Gruß
    Pitter



  • Warum schreibst du da Deklarationen von Funktionen mitten in den Code?
    Wenn das Programm in die Zeile 7 reingeht, konnte die Datei nicht geöffnet und nicht erstellt werden. Selbst wenn sie zu öffnen ginge, warum willst du sie in Zeile 16 noch einmal öffnen?
    Angenommen Zeile 16 funzt und die Datei wird geöffnet, angenommen sie wird auch eingelesen, dann springt das Programm in Zeile 30 an die aufrufende Funktion, d.h. alles ab Zeile 33 wird nicht ausgeführt.



  • Hallo Big Brother,

    ich sach ja... DAU am Start, aber ich versuch mich da rein zu kämpfen...

    Ok, mal abgesehen davon, dass das return 0 in Zeile 30 da weg muss...

    Warum kann denn das Script die XML nicht öffnen und in INVALID_HANDLE_VALUE läuft? Die Datei ist definitiv in dem Verzeichnis drin.

    HANDLE hFile6 = CreateFile(TEXT("\\My Flash Disk\\navigation\\licenses\feature.xml\0"), GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL, NULL);
    
    	if (hFile6 == INVALID_HANDLE_VALUE)
    

    Wie muss ich denn die obige Zeile umschreiben, dass mir beim Entfernen der Zeile

    FILE *file = fopen("\\My Flash Disk\\navigation\\licenses\feature.xml", "rb");
    

    das Script nicht in Fehler läuft?



  • Ich sehe momentan gar nicht, wozu du das hFile6 Handle überhaupt brauchst ...?
    Das Öffnen geht vermutlich in beiden Fällen schief, weil ein Backslash zwischen licenses und feature.xml fehlt:
    "\\My Flash Disk\\navigation\\licenses****feature.xml"
    Die \0 im TEXT Macro ist überflüssig.
    Du brauchst nur eine Zeile aus der Datei zu bearbeiten und liest dafür die ganze Datei ein?



  • Hallo,

    Ja *patsch* den Backslash hab ich übersehen... 👎

    Trotzdem liest das Script die Datei nicht ein, sondern schreibt mir das obligatorische 'NO' in das Textfile.

    Wenn ich den Bereich mit CreateFile raus nehme, hängt sich das Proggie auf dem PNA komplett auf...

    Das hfile wird vorher schon des Öfteren benötigt. So komme ich halt auf hfile6.
    Das Proggie ermittelt ja nicht nur die hier gezeigten beiden Werte aus der XML, sondern holt unter Anderem die Grösse einer bestimmten DLL, schaut, ob eine bestimmte Datei auf der SD-Karte liegt usw...

    Das Grundgerüst des Scriptteiles hab ich in dem defekten Thread von jemandem erhalten und umgeschrieben...

    Wie könnte ich das denn besser anstellen, statt die ganze XML einlesen???

    Kann sein, dass das für Euch Basics sind... aber ich bin ja noch am Anfang...



  • Lässt sich die Datei mit fopen öffnen?
    Pack doch mal diese Zeilen vor Zeile 3 und probier mal:

    FILE *file = fopen("\\My Flash Disk\\navigation\\licenses\\feature.xml", "rb"); 
        if (!file)
    	{
    		puts("Datei kann nicht geoffnet werden!");
    		fprintf(stdout, "%s\n", strerror(errno));
    	}
    	else
    		puts("Datei wurde geoffnet!");
    


  • 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).


Anmelden zum Antworten