Probleme mit FindfirstFile
-
Hallo zusammen,
ich möchte gerne die Anzahl der Dateien in einem Ordner ermitteln.
Hierzu habe ich bereits folgenden Code:void getAnzahHdcrlDateien() { WIN32_FIND_DATA FindFileData; HANDLE hFind; int nFiles = 0; hFind = FindFirstFile("C:\\Windows\\*", &FindFileData); if (hFind == INVALID_HANDLE_VALUE) { exit(0); } do { if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // aktuelles Element ist ein Verzeichnis // TODO: Rekursiven Aufruf implementieren } else { // aktuelles Element ist eine Datei nFiles++; } } while (FindNextFile(hFind, &FindFileData)); FindClose(hFind); printf("%d files.", nFiles); }Als Fehlermeldung kommt "Das Argument vom Typ ""const char *"" ist mit dem Parameter vom Typ "" LPCWSTR"" inkompatibel.
Wenn ich den Pfad mit LPCWSTR caste findet er keine Dateien.Ist bestimmt ein Anfängerfehler - SORRY!
-
FindFirstFileA
-
dann schreibt er als Fehlermeldung:
"Das Argument vom Typ "WIN32_FIND_DATA *" ist mit dem Parameter vom Typ "LPWIN32_FIND_DATAA" inkompatibel
-
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
-
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.
FindFirstFileverwendest, dann ist dies ein Makro. Wenn das MakroUNICODEdefiniert ist, dann evaluiertFindFirstFilezuFindFirstFileWund ansonsten zuFindFirstFileA.#ifdef UNICODE #define FindFirstFile FindFirstFileW #else #define FindFirstFile FindFirstFileA #endifMan kann aber
FindFirstFileWoderFindFirstFileAauch explizit verwenden.Das Makro
TEXTmacht im übrigen etwas ähnliches:#ifdef UNICODE #define TEXT(x) L##x #else #define TEXT(x) x #endifMarcusG 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.
-
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/251551Grü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.cFileNameden 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.
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.cFileNameden 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 ...
-
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 gleichwchar_t*. Auch die Empfehlung zuMultiByteToWideCharist seltsam. Es ist nicht nur die falsche Funktion, wenn man nachchar*konvertieren möchte (richtig wäreWideCharToMultiByte), 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.