[C++] Dateisuche in C++ mit Windows API

Crayzee Ivan

Mitglied
Hi!

Ich habe mir eine kleine Funktion geschrieben, an die ich einen Pfad sende (also "C:\" oder so), und die mir eine Liste (ein Array) der Unterverzeichnisse zurückgibt. Das ganze basiert auf der Windows-API, die verwendeten API-Calls sind FindFirstFile, FindNextFile, FindClose.

Die generelle Anwendung dieser Calls ist nicht mein Problem, die Funktion tut was sie soll, sie gibt alle Verzeichnisse zurück. Mein Problem ist aber, das die Ordner "." und ".." (jedem DOS-Veteranen sollten sie bekannt sein) auch aufgelistet werden. Hinzu kommt, das unter Windows XP (welches ich benutze) die Auslagerungsdatei "pagefile.sys" auch das Dateiattribut FILE_ATTRIBUTE_DIRECTORY hat, und somit auch aufgelistet wird.

Um dies zu verhindern habe ich folgendes probiert:
Code:
...
if (wfd.cFileName != "." && wfd.cFileName != ".." && wfd.cFileName != "pagefile.sys")
{
    Liste erweitern, Dateiname hinzufügen etc..
}
...
wfd ist ein Variable vom Typ WIN32_FIND_DATA, die von FindFirstFile und FindNextFile benutzt wird, um die gefundene Datei zurückzugeben, und cFileName ist der Name der gefundenen Datei.
Nach allem was ich finden konnte müsste die if-Abfrage alle Dateien aussortieren, die ".", ".." oder "pagefile.sys" als Namen haben.
Nur leider tut sie das nicht.

Allerdings: Ich habe erst vor kurzem angefangen mich ernsthaft mit C++ zu beschäftigen, und ich habe vorher VB programmiert, was mir einige Probleme bereitet hat (wie, es gibt keine String-Variable in C++?! :)). Vielleicht habe ich deswegen etwas übersehen oder ähnliches.
Ich hätte die ganze Funktion hier posten können, aber soweit ich feststellen konnte, hängt mein gesamtes Problem an dieser if-Abfrage, und wie gesagt, alles andere funktioniert bestens.

Ich hoffe mir kann jemand hiermit helfen...

-Crayzee Ivan
 
win32_find_data ist ein struct mit folgendem aufbau:
Code:
typedef struct _WIN32_FIND_DATA 
{ 
    DWORD dwFileAttributes; 
    FILETIME ftCreationTime; 
    FILETIME ftLastAccessTime; 
    FILETIME ftLastWriteTime; 
    DWORD nFileSizeHigh; 
    DWORD nFileSizeLow; 
    DWORD dwOID; 
    TCHAR cFileName[MAX_PATH]; 
    CHAR cAlternateFileName[14];
} WIN32_FIND_DATA;

in der bedingung seh ich zwar nichts falsches, aber ich würd das ganze etwas anders schreiben:
Code:
if (! ((wfd.cFileName == ".") || (wfd.cFileName == "..")) && (wfd.dwFileAttributes != FILE_ATTRIBUTE_HIDDEN)) { ...
dass ich deine bedingung negiere, ist geschmackssache, deins sollte trotzdem funktionieren. aber die pagefile.sys würd ich nicht einzeln prüfen, sondern einfach alle dateien ausblenden, die versteckt sind.
 
Hm, danke, hat leider nichts gebracht. Ich versteh das nicht, die if-Abfrage tuts nicht. Ich habe sogar die cFileName-Variablen an '\0' mit einer Funktion abgeschnitten, da sie immerhin 160 Zeichen enthalten, aber das bringt auch nichts. War auch eher ne Verzweiflungstat, denn eigentlich sollte er beim vergleichen von zwei strings doch bei '\0' aufhören, oder?
Also, keine Ahnung nach wie vor... :confused:

Vielleicht hatte ja einer schon dasselbe Problem und hat ne Lösung gefunden? *hoff*

-Crayzee Ivan
 
Code:
typedef struct _WIN32_FIND_DATA 
{ 
    DWORD dwFileAttributes; 
    FILETIME ftCreationTime; 
    FILETIME ftLastAccessTime; 
    FILETIME ftLastWriteTime; 
    DWORD nFileSizeHigh; 
    DWORD nFileSizeLow; 
    DWORD dwOID; 
    TCHAR cFileName[MAX_PATH];   // das ist dein Problem 
    CHAR cAlternateFileName[14];
} WIN32_FIND_DATA;

Also wie asphyxia richtig gesagt hat ist _WIN32_FIND_DATA eine struct und hat eine Eigenschaft cFileName. Dies ist ein char-Array das heißt wenn du es mit einer "String-Konstanten" vergleichen willst, dann geht das so nicht, da WIN32_FIND_DATA.nFilename ein Zeiger ist, der auf die Anfangsadresse des Arrays zeigt. Und das was du dabei versuchtst ist 2 Zeiger miteinander zu vergleichen und das geht nicht !!!

Also solltest du WIN32_FIND_DATA.nFilename am besten in einen CString "casten":

Code:
if (! (((CString)wfd.cFileName == ".") || (CString)wfd.cFileName == "..")) && ((CString)wfd.dwFileAttributes != FILE_ATTRIBUTE_HIDDEN)){
...
}

Gruss Homer
P.S. ich hab das jetzt nicht getestet, aber das müsste gehen.
 
Ok, danke, etwas ähnliches hatte ich auch schon vermutet ;-), leider ist CString eine MFC-Klasse (denke ich doch, oder?), und ich benutze Dev-C++ zum coden. Ich habe zwar auch VC++ (naja, sagen wir mal, geliehen :rolleyes: ), aber ich benutze es nicht so gerne...

Aber das mit den Pointern hilft mir trotzdem, ich werde mal versuchen da etwas mit zu machen.

Danke noch mal an euch,
-Crayzee Ivan
 
Das mit dem CString war ja auch nur ein Dankanstoß, in der Lib mit der du Programmierst, wird es ja warscheinlich auch etwas geben, das so ähnlich wie der CString der MFC ist.

Gruss Homer
 
Hm, wenn mir jetzt noch einer sagen könnte, wie diese entsprechende Funktion unter Dev-C++ heißt (compiler: MingW), dann bin ich wunschlos glücklich :) ;-)

Gruß,
-Crayzee Ivan
 
es gibt eine c++-library namens string, und eine mit windows-funktionen. wenn du die einbindest, kannst du auch auf WIN32_FIND_DATA zugreifen. das würde dann z.b. so aussehen:
Code:
#include <string>
#include <windows.h>

// ...

if ((string)wfd.cFileName != "." && (string)wfd.cFileName != ".." && wfd.dwFileAttributes != FILE_ATTRIBUTE_HIDDEN)

hab ich nicht ausprobiert, aber sollte meines wissens nach gehen.
 
Ich habe mich gerade um die windows.h herumgeschummelt, FindFirstFile etc sind auch in io.h drin, und die ist ein wenig kleiner :)

Wie dem auch sei, ich habe mir ne funktion geschrieben, die die Strings char für char vergleicht und dann true oder false zurückgibt. Mag zwar nicht die schnellste methode sein, aber für meine Zwecke ausreichend ;-)

Nochmals danke an euch, ich hoffe ich kann auch mal jemandem helfen :)

-Crayzee Ivan
 
wenn du zwei strings zeichenweise vergleichen willst, kannst du doch auch einfach die strcmp()-funktion aus der string.h nehmen. die macht nämlich genau das gleiche. :)
 
Zurück