WIN32/WINAPI File I/O



  • Soweit ich das sehe geht es im ganzen Tutorial nur um Fenster, Dateien werden nur am Rande erwähnt.
    Du kannst einfach den gesamten Code aus dem Tutorial kopieren und es sollte laufen, dann noch etwas abändern damit der Pfad stimmt.
    Alternativ lass das mit den Fenstern sein und kümmer dich nur um Dateien.
    Benutze doch bitte nächstes Mal die C++-Code-Tags unter dem 😞 -Smiley (Der sieht so aus, weil er immer ignoriert wird).

    #include <Windows.h>
    #include <stdio.h>
    
    wchar_t *getReadableErrorMessage(){ //hilfskram, nicht wichtig
    	static wchar_t buffer[1024] = L"Fehler beim Generieren der Fehlernachricht";
    	FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buffer, sizeof buffer / sizeof *buffer, 0);
    	return buffer;
    }
    
    int main(){
    	HANDLE file = CreateFileA("C:\\AMP1.txt", GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0);
    	if (file == INVALID_HANDLE_VALUE){
    		wprintf(L"Konnte Datei nicht öffnen: %s\n", getReadableErrorMessage());
    		return 0;
    	}
    	wchar_t buffer[1024];
    	DWORD read;
    	if (!ReadFile(file, buffer, sizeof buffer / sizeof *buffer - 1, &read, 0)){
    		wprintf(L"Konnte Datei nicht lesen: %s\n", getReadableErrorMessage());
    		return 0;
    	}
    	buffer[read] = 0;
    	wprintf(L"Inhalt der Datei:\n%s\n", buffer);
    	CloseHandle(file);
    	//TODO: benutze swscanf oder so um die Zahlen aus buffer zu lesen
     }
    

    Samstagmorgen? 😕



  • Moin nwp3,

    das hat so leider noch nicht geklappt. Aber aufgeben gilt nicht.
    Nachstehend die Funktion, ich weiß nicht was wo hin gehört und bleibe somit unterstützungsbedürftig. Würde mich freuen, wenn Du weiter hilfst.
    Gruß aus HH
    mat65

    [code="cpp"]
    bool OpenGL_Init :: opengl_draw_scene (){
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLineWidth(2.5);

    /////////////FRAME I /////////////

    A= 0.0f;
    B= 0.0f;
    C= -15.0f;

    glBegin (GL_LINE_LOOP);

    glColor3f (0.0f,1.0f,0.0f);

    glVertex3f ( A, B, C);
    glVertex3f ( 0.75f, 0.5f, -15.0f);
    glVertex3f ( 0.75f, 2.0f, -15.0f);
    glVertex3f ( 0.00f, 1.5f, -15.0f);
    glEnd();
    return true;
    }



  • Was hat denn das mit Dateien zu tun? Irgendwie weiß ich nicht mehr was die Frage ist.



  • Die werte a, b, c sollen aus der datei ausgelsen umd dann als variable weitergenutzt werden um nachstehendes viereck zu zeichnen. Das waere der bezug zu den dateien. Bin gerade mit meiner tochter auf ihrem abi ball. Deswegen ganz kurz.



  • Hmm, ich will eigentlich nicht deine Aufgaben machen. Du kannst das Viereck darstellen (nehme ich mal an), du kannst jetzt Dateien einlesen und um aus dem Textstring aus der Datei Zahlen zu machen gibt es wie gesagt swscanf (und Alternativen).
    Damit hast du doch alles.
    Mit "das hat so leider noch nicht geklappt" kann ich übrigens nicht viel anfangen. Programm kompiliert nicht, Programm kompiliert und stürzt ab, Programm kompiliert und läuft aber tut das Falsche... Möglichst auf eine Zeile reduziert wo du sagen kannst was du tun willst, was passiert und was passieren sollte bzw. die Fehlermeldung des Compilers. "Beispielprogramm zum Einlesen von Dateien ändert mein Viereck nicht" gilt nicht als Fehler ^^
    Wahrscheinlich musst du dich jetzt hinsetzen und die Funktionen schreiben, die du brauchst. Du hast ja gute Vorlagen.

    ps: Mir fällt gerade auf, dass meine getReadableErrorMessage-Funktion ist nicht so der Hit ist -.-
    Will ja niemanden mit falschen Fehlermeldungen aufs Glatteis führen.

    const wchar_t *getReadableErrorMessage(){ //hilfskram, nicht wichtig
        static wchar_t buffer[1024];
        if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buffer, sizeof buffer / sizeof *buffer, 0)
            return buffer;
        return L"Fehler beim Generieren der Fehlernachricht";
    }
    


  • Moin nwp3,

    http://www.cplusplus.com/reference/cwchar/swscanf/ habe ich versucht zu verstehen, klappte nicht so richtig.
    Wo ist hier der wide string, wo in meiner Funktion, bin weiter verwirrt?
    [code="cpp"]
    /* swscanf example */
    #include <wchar.h>

    int main ()
    {
    wchar_t sentence [] = L"Michael is 10 years old";
    wchar_t str [20];
    int i;

    swscanf (sentence,L"%ls %*s %d",str,&i);
    wprintf (L"%ls -> %d\n",str,i);

    return 0;
    }

    Mein Program läuft so wie gehabt, es fehlt eben nur der Punkt mit den Koordinaten A,B,C
    Ich beschäftige mich schon seit Wochen mit dieser Aufgabe und wäre für die Lösung sehr dankbar, auch wenn das vlt nicht der tiefer Sinn eines Forums ist.
    Schönen Sonntag Mathias

    [code="cpp"]
    #include "stdafx.h"
    #include "opengl_init.h"
    #include <Windows.h>
    #include <stdio.h>
    #include <wchar.h>

    float A,B,C;
    // habe noch eine Klammer ergänzt
    const wchar_t *getReadableErrorMessage(){ //hilfskram, nicht wichtig
    static wchar_t buffer[1024];
    if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buffer, sizeof buffer / sizeof *buffer, 0))
    return buffer;
    return L"Fehler beim Generieren der Fehlernachricht";
    }
    ...
    bool OpenGL_Init :: opengl_draw_scene (){
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLineWidth(2.5);
    /////////////FRAME I /////////////
    HANDLE file = CreateFileA("C:\\AMP\\AMP1.txt", GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0);
    if (file == INVALID_HANDLE_VALUE){
    wprintf(L"Konnte Datei nicht öffnen: %s\n", getReadableErrorMessage());
    return 0;
    }
    wchar_t buffer[1024];
    DWORD read;
    if (!ReadFile(file, buffer, sizeof buffer / sizeof *buffer - 1, &read, 0)){
    wprintf(L"Konnte Datei nicht lesen: %s\n", getReadableErrorMessage());
    return 0;
    }
    buffer[read] = 0;
    wprintf(L"Inhalt der Datei:\n%s\n", buffer);
    CloseHandle(file);

    /* A 0.0f aus "C:\\AMP\\AMP1.txt"
    B 0.0f
    C -15.0f*/

    glBegin (GL_LINE_LOOP); //Frame 1(100%)
    glColor3f (0.0f,1.0f,0.0f);
    glVertex3f ( A, B, C);
    glVertex3f ( 0.75f, 0.5f, -15.0f);
    glVertex3f ( 0.75f, 2.0f, -15.0f);
    glVertex3f ( 0.00f, 1.5f, -15.0f);
    glEnd();

    return true;
    }



  • Die cpp-Tags solltest du mit einem [/code] wieder zu machen.

    In der Datei steht sowas drin, richtig?:
    Name: Wert:
    fABpx0 0.0f
    fABpv0 1.0f
    fABpz0 1.0f
    iTEX_AREA_1 2

    wprintf(L"Inhalt der Datei:\n%s\n", buffer);
    

    Das sollte dir sagen, wo dein wide string ist, nämlich buffer, natürlich erst nachdem die Datei erfolgreich eingelesen wurde.
    printf kennst du doch, oder? sscanf ist fast genau das Gegenteil.

    Du willst also sowas in der Art:

    float A, B, C;
    int rueckgabewert = swscanf(buffer, L"Name: Wert:\n\
    fABpx0 %ff\n\
    fABpv0 %ff\n\
    fABpz0 %ff\n\
    iTEX_AREA_1 2",
    &A, &B, &C);
    if (rueckgabewert != 3)
        printf("Konnte %d/3 Variablen einlesen, Formatstring stimmt nicht mit Dateiinhalt überein", rueckgabewert);
    

    Das %f sagt ihm, dass an dieser Stelle ein float stehen soll. Der Rückgabewert sagt dir wieviele Variablen er eingelesen hat. Wenn rueckgabewert != 3 ist, dann ist was schief gegangen. In diesem Fall musst du den Formatstring mit dem Inhalt der Datei vergleichen. Die müssen übereinstimmen. Alternativ kannst du auch sagen, dass die Koordinaten immer nach einem Leerzeichen kommen. Mit strchr kannst du die Leerzeichen in deinem String finden. Die Unicodevariante heißt wcschr. Um nach einem String zu suchen ("fABpx0 " zum Beispiel) gibt es strstr/wcsstr, dessen Rückgabewert man mal ausgeben kann um zu sehen was er da gefunden hat. Dann halt an der Stelle mit einem einfachen swscanf(gefundeneStelle, L"%f", &A) direkt einlesen. Wobei strstr natürlich den String findet den er suchen sollte und nicht die Zahl, daher muss man da noch ein bisschen was machen.

    Du ließt übrigens jetzt in jedem Frame die Datei neu ein. Du willst die Datei bestimmt nur einmal einlesen.



  • nwp3, erstmal vielen Dank, wie kann ich überprüfen ob die Datei richtig eingelesen wurde? Gibt es da eine Form von Zwischenabfrage? Ich kenne auch printf nicht, glaube zu verstehen worum es geht. Hänge mich morgen wieder rein und wünsche erst mal einen schönen Sonntagabend. Einmal einlesen wäre genau das Richtige. Wenn ich mich für die Hilfe irgendwie erkenntlich zeigen kann, lass es mich wissen, ich halte das nicht für selbstverständlich.

    Gruß Mathias



  • mat65 schrieb:

    wie kann ich überprüfen ob die Datei richtig eingelesen wurde?

    In meinem Beitrag wo "Samstagmorgen? 😕 " steht hatte ich das geschrieben. Datei kann nicht geöffnet werden, Datei kann nicht gelesen werden usw. Ich hoffe das ist verständlich. Die WinAPI-Funktionen kann man bei der MSDN nachschlagen.

    Dann noch ein printf-Tutorial weil ich faul bin. Ich hoffe du kannst halbwegs englisch.
    fprintf tut dasselbe für Dateien, sprintf dasselbe für Strings, die w-Varianten für Unicode und die scan-Varianten zum Lesen statt Schreiben.
    Und ja, wenn man eh schon swscanf benutzt kann man auch gleich fwscanf benutzen.



  • Moin nwp3,
    weiter geht's. Ich habe deine Hinweise eingefügt und kompeliert, alles gut, nix passiert 😕 :

    int rueckgabewert = swscanf(buffer, L"Name: Wert:\n\fABpx0 %ff\n\fABpy0 %ff\n\fABpz0 %ff\n",&fABpx0, &fABpy0, &fABpz0); 
    
    //AREA//
    //fABpx0	= 0.0f; fABpy0	= 0.0f; fABpz0	= 1.0f; iTEX_AREA_1 = 2;		//"C:\\AMP\\IMAGE\\AIDA_14_Playground.jpg"
    

    iTEX_AREA_1 = 2 (int iTEX_AREA_1) wie lese ich int aus, wenn %f float ist?

    int main ()
    {
      char str[] = "This is a sample string";
      char * pch;
      printf ("Looking for the 's' character in \"%s\"...\n",str);
      pch=strchr(str,'s');
      while (pch!=NULL)
      {
        printf ("found at %d\n",pch-str+1);
        pch=strchr(pch+1,'s');
      }
      return 0;
    }
    

    habe ich gefunden, ... ist unser "buffer" hier "str"? gibt es iwo eine Tabelle mit diesen %f,%ff vielleicht würde das helfen=?
    Was du schreibst verstehe ich, kann es aber iwie nicht umsetzen? Ich denke, ich habs, schwupps ist es wieder weg.
    Gruß Mathias

    PS:

    und schon mit Zeilennummern, lerne ... langsam



  • mwp3 vielen Dank für den Link 🙂
    Ich möchte nur die Variablen aus der Datei auslesen und gern auf einmal für alle Koordinaten und Texturen (das sind nur knapp 200 zeilen)
    Muß auch nicht pro Frame sein und gern im Format fABpx0 0.0f, bzw iTEX_AREA_1 2, mit 2 als integer.
    Hätte nie gedacht, dass das so kompliziert ist, vor 20 Jahren mit TP 5 war das irgendwie anders.
    Aufgeben gilt nicht, aber alleine geht es auch nicht.
    GM



  • nwp3, lesen hilft mir ...
    Specifier Description Example
    f Display the floating point number using decimal representation 3.1415
    e Display the floating point number using scientific notation with e 1.86e6 (same as 1,860,000)
    E Like e, but with a capital E in the output 1.86E6
    g Use shorter of the two representations: f or e 3.1 or 1.86e6
    G Like g, except uses the shorter of f or E 3.1 or 1.86E6

    Variable type Length Modifier Example
    short int, unsigned short int h short int i = 3; printf( "%hd", i );
    long int or unsigned long int l long int i = 3; printf( "%ld", i );
    wide characters or strings l wchar_t* wide_str = L"Wide String"; printf( "%ls", wide_str );
    long double L long double d = 3.1415926535; printf( "%Lg", d );

    [code="cpp"]
    int rueckgabewert = swscanf(buffer, L"Name: Wert:\n\fABpx0 %ff\n\fABpy0 %ff\n\fABpz0 %ff\n", %h\n,
    &fABpx0, &fABpy0, &fABpz0, &iTEX_AREA_1);
    if (rueckgabewert != 4)
    printf("Konnte %d/4 Variablen einlesen, Formatstring stimmt nicht mit Dateiinhalt überein", rueckgabewert);
    [/code]
    if (rueckgabewert != 4) //ungleich 4
    printf("Konnte ?KEINE? %d/4 Variablen einlesen, Formatstring stimmt nicht mit Dateiinhalt überein", rueckgabewert);

    oder habe ich da jetzt einen Denkfehler?
    GM



  • Moin nwp3,

    ich habe wprintf, swscanf,printf wie beschrieben, aber keinen Erfolg.
    Welche Frage sollte ich jetzt stellen? Mir fällt nur "woran liegt's" ein.
    Ich erhalte keine Fehlermeldung beim Kompilieren und die Ausführung erfolgt eben nur der die entsprechenden Werte. Wie geht's jetzt weiter. Gruß Mathias



  • Hab denn Thread nur überflogen. Aber Pauschal würde ich sagen, debug das ganze einfach mal dann siehst du schnell wo das Problem liegt.



  • moin lowbyte, ich debuge mit F5, es gibt keine Fehlermeldung. Gruß



  • oh mein gott



  • danke, ..., daran habe ich am Anfang dieses Projektes auch schon gedacht,
    es half in Puncto Leidensfähigkeit und Durchhaltevermögen.



  • Dann kannst du denn debugger nicht bedienen, oder weisst nichts damit anzufangen. Denn auf Fehlermeldungen vom debugger zu warten...ist irgendwie... 🙄



  • Moin lowbyte, ... "einem "dummen" zeigen, dass du "schlauer" bist" (P.Fox), was hilft es Dir nachts um zwei? Würde mich freuen, wenn Du mir weiterhilfst. Ich google mich nun weiter zum Thema debuging durch.



  • Problem eingrenzen und danach mit Breakpoints step by step die Stelle durchgehen. Überprüfen ob die Variablen auch die Werte haben die Du brauchst, oder ob Funktionen die richtigen Parameter haben. So siehst du relativ schnell ob du mittendrin etwas zerschiesst. Und immer schön Rückgabewerte Prüfen!
    Dann findest du früher oder später dein miesen Bug. Oder hast du doch irgendwo ein Logikfehler drin?! Finde es heraus...

    Ps: Und das du dumm bist, habe ich nie gesagt.


Anmelden zum Antworten