Problem beim Einlesen einer TXT-Datei



  • Ist vielleicht etwas nervig, aber malloc ist einer der Fälle, in denen man NICHT casten sollte.



  • Wenn Du mit fread () eine Textdatei einliest, musst Du die ominöse "Terminierende Null" per Hand setzen.
    Deshalb auch bei malloc () immer i.e. "iFileSize + 1" :

    ...
     buffer = (char *) malloc((iFileSize+1) * sizeof(buffer));
     buffer [iFileSize] = '\0'; // <- so oder so ähnlich
    ...
    

    Warum der Schliessen-Button versagt, lässt sich aus der Ferne nicht sagen. Möglicherweise hast Du in der WM_CLOSE ein "return 0" als letzte Anweisung.
    Poste mal die AppWndProc () in ihrer aktuellsten Version (mit allen Änderungen).
    🙂



  • du hast kein DestroyWindow in der WM_CLOSE und gibts 0 zurück du Holzkopf!



  • in keinem windowsbuch findeste fread, malloc und diesen ganzen standartmist. datein werden bei windows mit createfile geöffnet !



  • tenchou schrieb:

    du hast kein DestroyWindow in der WM_CLOSE und gibts 0 zurück du Holzkopf!

    Einfach unfassbar, was man sich hier alles an den Kopf werfen lassen muss. Dieses Newbie-feindliche Verhalten kotzt mich dermaßen an, das glaubst du gar nicht. Wenn du mich nur beleidigen willst, kannst du dir weitere Postings getrost sparen. Komisch, dass sich das alle nur anonym trauen... Naja, sei es drum.

    @ merker:

    Nun stürzt das Programm nicht mehr ab und lässt sich auch normal beenden, danke schonmal ;). Bleibt noch das Problem mit den Zeichen in der TXT. Der Text wird nämlich auch nicht gespeichert, wenn ich ihn ändere. Hier mal der Code:

    LRESULT CALLBACK AppWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) 
    {
    
       HDC hdc;
       PAINTSTRUCT ps;
    
       EnableWindow(g_hButton2, FALSE);
       EnableWindow(g_hButton3, FALSE);
    
       static HWND hEdit;
    
       switch(uiMsg) 
       { 
          case WM_CREATE:
             Create_GUI_Interface(hwnd);
    
             FILE *fz;
             char *buffer;
             int iFileSize;
    
             fz = fopen("Bla.txt", "rb");
             if( fz != NULL)
             {
                 fseek(fz, 0, SEEK_END);
                 iFileSize = ftell(fz);
                 buffer = (char*)malloc((iFileSize + 1) * sizeof(buffer));
                 buffer [iFileSize] = '\0';
    
                 fseek(fz, 0, SEEK_SET);
                 fread(buffer, 1, iFileSize, fz);
                 fclose(fz);
             }
    
             // Erzeugt im Fenster ein Editfeld.
             hEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
                     TEXT("EDIT"),
                     TEXT(buffer),
                     WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL,
                     10,                                                         // Abstand zum linken Rand
                     100,                                                        // Abstand zum oberen Rand
                     400,                                                        // Feldbreite
                     350,                                                        // Feldhöhe
                     hwnd,
                     NULL,
                     g_hInstance,
                     NULL);
    
             free(buffer);
             return 0;
    
          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps);
                     SetBkMode (hdc, TRANSPARENT);
    
                     LFTahoma.lfHeight = 80;
                     LFTahoma.lfWeight = 0;
                     hFont = (HFONT)SelectObject (hdc, CreateFontIndirect (&LFTahoma));
                     TextOut (hdc, 85, 5, "Blubb", 5);
                     DeleteObject (SelectObject (hdc, hFont));
    
                     LFArial.lfHeight  = 15;
                     LFArial.lfWeight  = 0;
                     hFont = (HFONT)SelectObject (hdc, CreateFontIndirect (&LFArial));
                     TextOut (hdc, 4, 527, "(c) by Itachi", 13);
                     DeleteObject (SelectObject (hdc, hFont));
                     EndPaint (hwnd, &ps);
          return 0;
    
          case WM_COMMAND: 
             switch( LOWORD(wParam) ) 
             {
                case ID_BUTTON:
                   if( HIWORD(wParam) == BN_CLICKED )
                   {
                      int Confirm = MessageBox (NULL, "Programm wirklich beenden?", g_lpszAppTitle, MB_YESNO | MB_ICONEXCLAMATION);
                      {
                          if (IDYES == Confirm)
                          {
                                    SendMessage(hwnd, WM_CLOSE, 0, 0);
                          }
                      } 
                   } 
                   break;
    
                case ID_BUTTON2:
                   if( HIWORD(wParam) == BN_CLICKED )
                   { 
                      ShowMessage("Dieser Button ist deaktiviert!");
                   } 
                   break;
    
                case ID_BUTTON3:
                   if( HIWORD(wParam) == BN_CLICKED )
                   { 
                      ShowMessage("Dieser Button ist deaktiviert!");
                   } 
                   break;
             } 
             return 0;
    
          case WM_CLOSE:
          {
               FILE *fz;
               char *buffer;
               int iLength;
    
               iLength = GetWindowTextLength(hEdit);
    
               buffer = (char*)malloc((iLength + 1) * sizeof(buffer));
               buffer [iFileSize] = '\0';
    
               GetWindowText(hEdit, buffer, iLength+1);
    
               fz = fopen("Bla.txt", "wb");
               fwrite(buffer, 1, iLength, fz);
               fclose(fz);
    
               free(buffer);
          }
    
          case WM_DESTROY: 
             PostQuitMessage(0);
             return 0; 
       } 
    
       return DefWindowProc(hwnd, uiMsg, wParam, lParam); 
    }
    


  • 1. Du hast ein Fallthrough in deiner WM_CLOSE Behandlung und 2. du hast meinen Ratschlag nicht umgesetzt. Und was zur Eule soll denn das hier bewirken:

    buffer = (char*)malloc((iLength + 1) * sizeof(buffer));
               buffer [iFileSize] = '\0';
    


  • tenchou schrieb:

    1. Du hast ein Fallthrough in deiner WM_CLOSE Behandlung und 2. du hast meinen Ratschlag nicht umgesetzt.

    1. Hilft es mir recht wenig, wenn du irgendwelche Begriffe verwendest, die mir nicht geläufig sind,

    2. war dein Post eine Beleidigung und kein Ratschlag...
    __________________________________________________________

    Eine genauere Formulierung wäre sehr hilfreich...



  • buffer = (char*)malloc((iFileSize + 1) * sizeof(buffer));
    

    ............................................................. ↑↑↑↑↑↑↑↑↑

    was soll den das werden? Bitte mal schnell nachdenken wie viel Speicher du da Reservierst! (Filesize mal 4 ?)

    änder das bitte, setzte den 0-Terminate nach dem einlesen der Datei, den so übergibts du ein 4mal größeren block.

    setzte das PostQuitMessage in WM_CLOSE



  • Bitte ignoriert Itachi einfach. Er will unsere Community nur ausnutzen.



  • C++-Style 😉

    #define IDC_EDT_TEXT	104
    #define IDC_BTN_CLOSE	105
    #define IDC_BTN_UNUSED1 106
    #define IDC_BTN_UNUSED2	107
    
    #include <string>
    #include <sstream>
    #include <fstream>
    
    LRESULT CALLBACK AppWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch (msg)
    	{
    	case WM_CREATE:
    		{
    			Create_GUI_Interface(hwnd);
    			HWND hWndEdit = CreateWindowExA(WS_EX_CLIENTEDGE, "edit", NULL,  WS_CHILD | WS_VISIBLE | WS_VSCROLL |
    											ES_MULTILINE | ES_AUTOVSCROLL, 10, 100, 400, 350, hWnd, reinterpret_cast<HMENU>(IDC_EDT_TEXT),
    											reinterpret_cast<HINSTANCE>(GetWindowLongA(hWnd, GWL_HINSTANCE)), NULL);
    			if (hWndEdit == NULL)
    			{
    				MessageBoxA(hWnd, "Fehler beim erstellen des Fensters!", NULL, 0);
    				return S_FALSE;
    			}
    
    			if (__argc > 1)
    			{
    				std::ifstream file_stream(__argv[1]);
    				std::stringstream ss;
    				ss << file_stream.rdbuf();
    				SendMessageA(hWndEdit, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(ss.str().c_str()));
    			}
    		} break; 
    	case WM_COMMAND:
    		{
    			switch (LOWORD(wParam))
    			{
    				case IDC_BTN_CLOSE:
    					{
    						if (HIWORD(wParam) == BN_CLICKED && 
    							MessageBoxA(hWnd, "Programm wirklich beenden?", "MyApp", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    							SendMessageA(hWnd, WM_CLOSE, 0, 0);
    					} break;
    				case IDC_BTN_UNUSED1:
    					{
    						if (HIWORD(wParam) == BN_CLICKED
    							MessageBoxA(hWnd, "Dieser Button ist deaktiviert!", NULL, 0);
    					} break;
    				case IDC_BTN_UNUSED2:
    					{
    						if (HIWORD(wParam) == BN_CLICKED)
    							MessageBoxA(hWnd, "Dieser Button ist deaktiviert!", NULL, 0);
    					} break;
    			}
    		} break;
    	case WM_CLOSE:
    		{
    			std::string file_name(__argc > 1 ? __argv[1] : "output.txt");
    			std::ofstream file_stream(file_name.c_str());
    			if (!file_stream)
    				return S_FALSE;
    
    			unsigned int len = GetWindowTextLengthA(GetDlgItemA(hWnd, IDC_EDT_TEXT)) + 1;
    			char* buffer = new char[len];
    			GetWindowTextA(GetDlgItemA(hWnd, IDC_EDT_TEXT), buffer);
    			file_stream << buffer << std::endl;
    			delete [] buffer;
    		} break;
    	case WM_DESTROY:
    		{
    			PostQuitMessage(0);
    		} break;
    	default:
    		return DefWindowProc(hWnd, msg, wParam, lParam);
    	}
    	return S_OK;
    }
    

    😃 Na ok C++-Style würde ich noch anders machen ... aber ist schonmal so nen bissel schöner 😉



  • Itachi schrieb:

    Bleibt noch das Problem mit den Zeichen in der TXT. Der Text wird nämlich auch nicht gespeichert, wenn ich ihn ändere.

    Du hast in der WM_CLOSE eine Variable verwechselt :

    case WM_CLOSE: 
    { 
     int iLength; // <- der hier ist es
    ...
     buffer = (char*)malloc((iLength + 1) * sizeof(buffer)); 
    // buffer [iFileSize] = '\0'; 
     buffer [iLength] = '\0'; // <- also so hier
    ...
    }
    

    Beachte auch orr lol's Beitrag (... und nicht seine Wortwahl !) was es mit dem "sizeof(buffer)" auf sich hat.
    🙂



  • (D)Evil das hast du wirklich gut gelöst!
    Endlich mal was lesbar.



  • LRESULT CALLBACK AppWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) 
    { 
       ... 
       [b]static HANDLE hHeap = NULL;[/b] 
       [b]static LPSTR lpStrText;[/b] 
       ... 
       switch(uiMsg) 
       { 
       case WM_CREATE: 
    
          // Erzeugt im Fenster ein Editfeld. 
          ... 
    
          [b]lpStrText = ReadTextFile (TEXT("MeineDatei.txt")); [/b]
          return 0; 
       case WM_CLOSE: 
          [b]HeapFree (hHeap, 0, lpStrText);[/b] 
          return 0; 
       case WM_DESTROY: 
          PostQuitMessage(0); 
          return 0; 
      } 
       return DefWindowProc(hwnd, uiMsg, wParam, lParam); 
    } 
    
    LPSTR ReadTextFile (LPCWSTR FileName) 
    { 
       DWORD dwFileSize, dwBytesRead; 
       HANDLE hFile; 
       LPSTR *lpStrText; 
       hFile = CreateFile (FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
       if (hFile == INVALID_HANDLE_VALUE) 
          return (NULL); 
       dwFileSize = GetFileSize (hFile, NULL); 
       hHeap = GetProcessHeap (); 
       if ((lpStrText = (LPSTR *) HeapAlloc (hHeap, HEAP_ZERO_MEMORY, dwFileSize)) == NULL) 
          // Speicherzuordnung gescheitert - hab's noch nie erlebt, aber sicher ist sicher ... 
          goto fail; 
       ReadFile (hFile, lpStrText, dwFileSize, &dwBytesRead, NULL); 
    fail: 
       CloseHandle (hFile); 
       return lpStrText; 
    }
    

    Warum umständlich, wenn's auch vernünftig geht? 😞



  • @orr lol: Joar, hast Recht, sizeof(buffer) ist quatsch, ermittelt ja die Größe des Zeiger 🤡 -sorry. Muss natürlich heißen sizeof(char) (ist zwar hier 1 ist, aber bei UNICODE macht das -wie bereits gesagt- Sinn.).

    @schmidt-webdesign.net:
    goto - LOL. Der Code ist grässlich. Guck Dir mal (D)Evil's Code an, der läuft zwar nur auf ANSI, ist aber wesentlich schöner. Wobei Du bei Dir auch ein wischi-waschi zwischen wchar_t und char's hast... .



  • @all schrieb:

    Bitte ignoriert Itachi einfach. Er will unsere Community nur ausnutzen.

    Das ist einfach ungeheuerlich. Was muss ich mir hier denn noch anhören? Das ist das WinAPI-Forum und nicht das Forum zum User fertigmachen... Ständig kommt irgendein sinnentleerter Kommentar von der Seite, noch dazu von einem User, der sich soetwas nur traut, wenn er als Gast unterwegs ist ⚠. Meiner Meinung nach solltet ihr Gästen besser die Schreibrechte entziehen. Aber gut, das ist eure Sache...
    _______________________________________________________________________________

    Uff, da sind ja in der Zwischenzeit einige Antworten zusammengekommen :D. Ich habe jetzt mal den Code von (D)Evil probiert. Nun sagt mir der Compiler "ifstream is not a member of std". Hm, was habe ich denn nun übersehen? Irgendwo steckt schon wieder der Fehlerteufel ^^



  • CodeFinder schrieb:

    @orr lol: Joar, hast Recht, sizeof(buffer) ist quatsch, ermittelt ja die Größe des Zeiger 🤡 -sorry. Muss natürlich heißen sizeof(char) (ist zwar hier 1 ist, aber bei UNICODE macht das -wie bereits gesagt- Sinn.).

    Du immer mit deinem UNICODE, du Kohlkopf. sizeof(char) ist immer 1, ganz egal ob _UNICODE definiert ist, oder nicht.



  • CodeFinder schrieb:

    @schmidt-webdesign.net:
    goto - LOL. Der Code ist grässlich. Guck Dir mal (D)Evil's Code an, der läuft zwar nur auf ANSI, ist aber wesentlich schöner. Wobei Du bei Dir auch ein wischi-waschi zwischen wchar_t und char's hast... .

    Nix grässlich! Nennt sich elegante Fehlerbehandlung. Findet sich so sogar im Linux-Kernel. Kennt jeder gute (ANSI-)C-Programmierer ...

    http://blogex.schmidt-webdesign.net/



  • Itachi schrieb:

    Das ist einfach ungeheuerlich.

    Stimmt, aber ich würde sowas einfach ignorieren, wie merker schon gesagt hat 😉 .

    Itachi schrieb:

    Nun sagt mir der Compiler "ifstream is not a member of std". Hm, was habe ich denn nun übersehen? Irgendwo steckt schon wieder der Fehlerteufel ^^

    Hast Du denn die darüber stehenden Includes eingebunden, speziell:

    #include <fstream>
    

    Weiterhin: Hast Du einen C++-Compiler 🤡 ?



  • schmidt-webdesign.net (ni schrieb:

    Nennt sich elegante Fehlerbehandlung.

    Naja suum cuique...glaube, dass Du der einzige bist, der das so sieht... .



  • CodeFinder schrieb:

    Itachi schrieb:

    Das ist einfach ungeheuerlich.

    Stimmt, aber ich würde sowas einfach ignorieren, wie merker schon gesagt hat 😉 .

    Itachi schrieb:

    Nun sagt mir der Compiler "ifstream is not a member of std". Hm, was habe ich denn nun übersehen? Irgendwo steckt schon wieder der Fehlerteufel ^^

    Hast Du denn die darüber stehenden Includes eingebunden, speziell:

    #include <fstream>
    

    Weiterhin: Hast Du einen C++-Compiler 🤡 ?

    Die Includes waren drin, nur hat er sie irgendwie nicht genommen. Ich hab mal im Dateikopf etwas umgeräumt und nun geht es ^^

    Zumindest habe ich so die Fehler dezimiert. Bleiben allerdings noch ein paar. So sind ofstream, file_stream und GetDlgItemA undeclared. Kann es sein, dass mir noch eine Library fehlt?

    Und einen C++-Compiler habe ich natürlich. Ich verwende Dev-C++ 4.9.9.2. Einen besseren kenne ich leider nicht ;). Nun, der beste scheint er nicht zu sein ^^


Anmelden zum Antworten