WIN32/WINAPI File I/O
-
Moin,
für ein OpenGl Projekt möchte ich die Koordinaten eines Quadrats aus einer Datei auslesen und weiterverarbeiten. Die Msdn verstehe ich nicht. bzw. kann Sie nicht umsetzen.(VS2010)
Wer kann mir mit Rat und Tat zur Seite stehen?Grüße von der Küste
-
fopen, ifstream, CreateFile. Such dir eins aus, zum Auslesen von ein paar Koordinaten reichen jeweils alle drei.
-
Danke für dei schnelle Antwort, also nichts mit
"BOOL WINAPI WriteFile( _In_ HANDLE hFile, _In_ LPCVOID lpBuffer, _In_ DWORD ..."
ISt es dann am Ende mal wieder so einfach?
-
also "ReadFile" natürlich ...
-
...
-
CreateFile würde mit ReadFile + WriteFile funktionieren.
fopen mit fread, fwrite, fprintf und fscanf.
Beim ifstream/ofstream shiftest du halt irgendwas rein oder raus.Der Vorteil von CreateFile/ReadFile/WriteFile ist, dass du exakter sagen kannst, was du willst. Zum Beispiel kannst du eine Datei aufmachen, in der du und andere gleichzeitig lesen können und die automatisch gelöscht wird, sobald alle die Datei zugemacht haben. Daher gibt es auch ein paar extra Parameter, die du aber meist einfach 0 lassen kannst wenn du sowas nicht brauchst. Ich glaube jeder übergibt einfach immer 0 für LPSECURITY_ATTRIBUTES. Dein Problem mit der MSDN kann ich aber nicht nachvollziehen. Auf der Doku zu CreateFile steht doch alles was es zu wissen gibt. Und im "See also"-Abschnitt sind auch gleich ReadFile, WriteFile, DeleteFile und die *Ex-Varianten verlinkt.
fopen hingegen ist schön einfach, kann aber auch nicht so viel und man muss/kann mehr selber machen. Das wäre mein Favorit für das Lesen einiger Koordinaten.
ifstream ist manchmal einfacher, manchmal schwerer zu benutzen als fopen. Wenn du eher zu C++ neigst und Operatorüberladungen toll findest nimm ifstream.
-
Moin und vielen Dank für die Unterstützung!
Auf Youtube hat es mal angefangen mit einem Opengl Tutorial, super erklärt von " repect to DevFlame" und von mir teilweise verstanden. Msdn bedarf der Erklärung.www.win-api.de/tutorials.php?tutid=18 schrieb:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
static HWND hEdit;
switch(message) {
case WM_CREATE: {
FILE *fz;
char buffer = NULL;
int iFileSize;
fz = fopen("C:\\AMP\\AMP1.txt", "rb");
if(fz != NULL){
fseek(fz, 0, SEEK_END);
iFileSize = ftell(fz);
buffer = (char) malloc (sizeof(char)*iFileSize); //war buffer = malloc(iFileSize)
fseek(fz, 0, SEEK_SET);
fread(buffer, 1, iFileSize, fz); //read!!!!!!!!!
fclose(fz);
}// hEdit = CreateWindowEx(WS_EX_CLIENTEDGE,"edit",buffer, WS_CHILD | WS_VISIBLE |
WS_VSCROLL | ES_MULTILINE |ES_AUTOVSCROLL,
0, 0, 0, 0,hWnd,NULL,((LPCREATESTRUCT) lParam) ->
hInstance,NULL); // buffer <- das ist der Inhalt der Editfelds
free(buffer);
return 0;
}}}Machte für mich Sinn, ich weiß nur nicht genau wohin damit in meinem Code.
Meine Datei C:\\AMP1.txt (Excel, UnicodeText)
Name: Wert:
fABpx0 0.0f
fABpv0 1.0f
fABpz0 1.0f
iTEX_AREA_1 2Wie geht es für mich am Samstagmorgen weiter?
Still
-
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 2wprintf(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ß MathiasPS:
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.86E6Variable 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