Probleme mit FindfirstFile



  • MarcusG schrieb:

    Als Fehlermeldung kommt "Das Argument vom Typ ""const char *"" ist mit dem Parameter vom Typ "" LPCWSTR"" inkompatibel.

    Stell Dein Projekt von UNICODE um auf MBCS.

    Edit:
    Oder aber schreib:

    hFind = FindFirstFile(TEXT("C:\\Windows\\*"), &FindFileData);
    


  • benötige leider Unicode



  • Sorry, habe dein Edit überlesen - funktioniert!
    Vielen Dank!



  • Sorry, würde nochmal Eure Hilfe benötigen: Wie gibt man nun den jeweiligen Dateinamen (am liebsten mit Pfad) aus?



  • selbst gefunden: FindFileData.cFileName


  • Administrator

    Vielleicht etwas Erklärung hierzu:
    Viele WinAPI Funktionen sind tatsächlich doppelt vorhandeln. Einmal mit einem A am Ende (z.B. FindFirstFileA ) und einmal mit einem W am Ende (z.B. FindFirstFileW ). Das A ist ein Hinweis auf ASCII und somit der Zeit vor Unicode. W dagegen steht für Wide und steht für die UCS-2 Kodierung.

    Die Funktionen mit einem W am Ende erwarten Wide-Strings ( wchar_t , std::wstring , etc.). Wenn du ein Wide-String-Literal willst, dann musst du ein grosses L davor stellen. Also z.B:

    hFind = FindFirstFileW(L"C:\\Windows\\*", &FindFileData);
    //                    -^-
    

    Wenn du nun z.B. FindFirstFile verwendest, dann ist dies ein Makro. Wenn das Makro UNICODE definiert ist, dann evaluiert FindFirstFile zu FindFirstFileW und ansonsten zu FindFirstFileA .

    #ifdef UNICODE
    #define FindFirstFile FindFirstFileW
    #else
    #define FindFirstFile FindFirstFileA
    #endif
    

    Man kann aber FindFirstFileW oder FindFirstFileA auch explizit verwenden.

    Das Makro TEXT macht im übrigen etwas ähnliches:

    #ifdef UNICODE
    #define TEXT(x) L##x
    #else
    #define TEXT(x) x
    #endif
    

    MarcusG schrieb:

    Sorry, würde nochmal Eure Hilfe benötigen: Wie gibt man nun den jeweiligen Dateinamen (am liebsten mit Pfad) aus?

    Mit C++, C oder der WinAPI? Und worauf? Der Konsole?
    In deinem Code verwendest du nämlich C und die WinAPI, schreibst deine Frage aber ins C++ Forum 😉

    Grüssli



  • Danke für die Erklärungen!

    Nutze FindFirstFileW(L"....

    Wie kann man denn jetzt die gefundene Datei dann öffnen?
    Versuche die Datei mit FindFileData.cFileName an eine File Variable zu binden - funktioniert aber leider nicht......



  • MarcusG schrieb:

    funktioniert aber leider nicht......

    Das ist aber schade......



  • Swordfish schrieb:

    MarcusG schrieb:

    funktioniert aber leider nicht......

    Das ist aber schade......

    Sehr schade ... eine Idee warum nicht?



  • MarcusG schrieb:

    eine Idee warum nicht?

    Siehe meine Signatur.


  • Administrator

    Zudem bleibt die Frage im Raum: C oder C++? Mit der WinAPI? Laut deiner E-Mail willst du C++ lernen. Dein gezeigter Code hat aber nicht viel mit C++ zu tun. Zum Rest in der E-Mail: Nein, Danke.
    http://www.c-plusplus.net/forum/251551

    Grüssli



  • hFind = FindFirstFileW(L"D:\\Test\\*", &FindFileData); 
    if (hFind == INVALID_HANDLE_VALUE) { 
        exit(0);                            
        } 
    
        do { 
            if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 
                // aktuelles Element ist ein Verzeichnis  
            } else { 
                // aktuelles Element ist eine Datei 
                nFiles++; 
    		if (nFiles=1);
    		{
    		US.KeyFile=FindFileData.cFileName;
    		}
            } 
        } while (FindNextFile(hFind, &FindFileData)); 
    FindClose(hFind);
    

    Hier bringt mir die Zuweisung

    US.KeyFile=FindFileData.cFileName
    

    den Fehler: Ein Wert vom Typ WCHAR * kann keiner Entität vom Typ char * zugewiesen werden.

    Ich möchte "eigentlich" nur den ersten Dateinamen haben und diese Datei dann zum Lesen öffnen.

    Hoffe Ihr könnt mir bitte nochmal helfen.

    Danke!



  • MarcusG schrieb:

    Ein Wert vom Typ WCHAR * kann keiner Entität vom Typ char * zugewiesen werden.

    MultiByteToWideChar()

    Sonst:

    #include <iterator>
    #include <vector>
    #include <string>
    #include <fstream>
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    #include <windows.h>
    
    typedef std::basic_string< TCHAR > tstring;
    
    #ifdef UNICODE
    std::wostream &tcout = std::wcout;  
    #else /* UNICODE */
    std::ostream &tcout = std::cout;
    #endif /* UNICODE */
    
    int main()
    {
    	std::srand( static_cast< unsigned >( std::time( 0 ) ) );
    
    	WIN32_FIND_DATA find_data = {};
    	HANDLE find_handle = FindFirstFile( TEXT( "*" ), &find_data );
    
    	if( find_handle != INVALID_HANDLE_VALUE ) {
    
    		std::vector< tstring > files;
    
    		do {
    
    			tcout << find_data.cFileName << '\n';
    			files.push_back( find_data.cFileName );
    
    		} while( FindNextFile( find_handle, &find_data ) );
    
    		tstring random_file_name = files[ std::rand() % ( files.size() - 1 ) ];
    		tcout << TEXT( "\nContent of \"" ) << random_file_name << TEXT( "\":\n" );
    
    		std::ifstream file( random_file_name );
    		std::cout << file.rdbuf() << '\n';
    	}
    }
    


  • MarcusG schrieb:

    Hier bringt mir die Zuweisung

    US.KeyFile=FindFileData.cFileName
    

    den Fehler: Ein Wert vom Typ WCHAR * kann keiner Entität vom Typ char * zugewiesen werden.

    Das Gleiche wie vorher:
    US.KeyFile ist vom Typ char*, sollte aber vom Type TCHAR* sein ...


  • Administrator

    Kompiliert ihr eigentlich wirklich noch Software ohne Unicode? Oder wieso empfiehlt ihr alles Code, welcher auch zu ISO 8859 kompatibel ist? Wieso nicht gleich ausschliesslich die Unicode Varianten verwenden?

    Erst recht wenn MarcusG sagt, dass er Unicode verwenden muss?

    Also nein, nicht TCHAR* verwenden, sondern gleich wchar_t* . Auch die Empfehlung zu MultiByteToWideChar ist seltsam. Es ist nicht nur die falsche Funktion, wenn man nach char* konvertieren möchte (richtig wäre WideCharToMultiByte ), sondern auch sehr fragewürdig sowas überhaupt zu empfehlen.

    Grüssli



  • Dravere schrieb:

    Erst recht wenn MarcusG sagt, dass er Unicode verwenden muss?

    Dass er Unicode verwenden muss, ihm aber niemand sagt, wie das vernünftig gemacht wird, ist doch mindestens merkwürdig. Könnte es nicht sein, dass bei denen, die ihm sagen, dass er es so machen muss, entsprechende Kenntnisse auch nur rudimentär vorhanden sind?
    Könnte es dann weiter nicht sein, dass man über kurz oder lang beschließt, okay, wir kriegen das nicht hin, machen wir erst mal wieder MBCS.
    Und dann ist er froh, wenn er TCHAR* statt wchar_t* genommen hat.


Anmelden zum Antworten