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



## Crayzee Ivan (30. Juli 2002)

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:

```
...
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


----------



## Dario Linsky (30. Juli 2002)

win32_find_data ist ein struct mit folgendem aufbau:

```
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:

```
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.


----------



## Crayzee Ivan (31. Juli 2002)

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... 

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

-Crayzee Ivan


----------



## Daniel Toplak (1. August 2002)

> ```
> typedef struct _WIN32_FIND_DATA
> {
> DWORD dwFileAttributes;
> ...



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":


```
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.


----------



## Crayzee Ivan (2. August 2002)

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  ), 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


----------



## Daniel Toplak (2. August 2002)

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


----------



## Crayzee Ivan (2. August 2002)

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


----------



## Dario Linsky (2. August 2002)

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:

```
#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.


----------



## Crayzee Ivan (3. August 2002)

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


----------



## Dario Linsky (3. August 2002)

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.


----------



## Crayzee Ivan (3. August 2002)

*hmpf*

Oh - mist =). Na egal, hat trotzdem spaß gemacht zu coden 
Außerdem, learning by doing, oder?

In diesem Sinne,
-Crayzee Ivan


----------

