FindFirst geht nicht



  • achso und C++ 8.0 benutz ich 🙂



  • Ich nehme mal an, Du hast UNICODE definiert. Deine Stringdeklaration ist falsch, richtig wäre es so:

    TCHAR dirname[] = _T("f:\\*.*");
    

    Und der Aufruf von FindFirstFile lautet:

    hand = FindFirstFile(dirname, &finddata);
    


  • Bzw. ohne UNICODE:

    char dirname[] = "f:\\*.*";
    
    hand = FindFirstFile(dirname, &finddata);
    

    Noch ein Tip: GetLastError(), aufgerufen direkt nach einer fehlgeschlagenen API-Funktion, gibt einen aussagekräftigeren Fehlerkode zurück.



  • Ohne Unicode (also ANSI) ist folgendes korrekt:

    WIN32_FIND_DATAA finddata;
    char dirname[] = "f:\\*.*";
    hand = FindFirstFileA(dirname, &finddata);
    


  • das teste ich dann gleich mal und sage vielen dank.

    gruß
    Daniel



  • Die korrekte Version wäre natürlich:

    WIN32_FIND_DATA finddata; 
    TCHAR dirname[] = _T("f:\\*.*"); 
    hand = FindFirstFile(dirname, &finddata);
    

    Siehe auch: Listing the Files in a Directory
    http://msdn.microsoft.com/library/en-us/fileio/fs/listing_the_files_in_a_directory.asp



  • ja so wie du es jetzt geschrieben hast hab ichs auch eingebaut und alles funktioniert ohne fehler NUR wird mir lediglich der erste Buchstabe vom Dateinamen ausgegeben, obwohl _tcslen(finddata.cFileName) jeweils die richtige Länge anzeigt.

    Scheint mir so als ob gerade wieder alles schiefgeht was nur schiefgehen kann.

    Gruß
    Daniel



  • printf durch wprintf ersetzen und es läuft. wer hätte das gedacht 🙂



  • Wenn du schon mit TCHAR's arbeitest, ist vielleicht _tprintf() am passendsten (das wird je nach UNICODE-Einstellungen als printf() oder wprintf() übersetzt).



  • prinzipiell funktioniert die dateianzeige, nur es fehlen in jedem verzeichnis das ich bisher getestet habe immer ein paar dateien. Was kann das sein?

    Gruß
    Daniel

    #define  _WIN32_WINNT  0x0501
    
    #include <windows.h>
    #include <string.h>
    #include <stdio.h>
    #include <tchar.h>
    
    int main(void)
    {
    	WIN32_FIND_DATA finddata;
    	HANDLE hand;
    	_TCHAR dirname[]=_T("f:\\TEMP\\*.*");
    
    	DWORD dw=GetLastError();
    
    	hand=FindFirstFile(dirname,&finddata);
    
    	if (hand==INVALID_HANDLE_VALUE)
    	{
    	printf("Hier geht nix!\n");
    	return(-1);
    	}
    	else
    	{
    
    wprintf(_T("%s\n"),finddata.cFileName);
    	while (FindNextFile(hand,&finddata) !=0)
    	{
    		_tprintf(_T("%s\n"),finddata.cFileName);
    
    		FindNextFile(hand,&finddata);
    	}
    
    	FindClose(hand);
    
    	}	
    return (0);
    }
    


  • Du rufst das "FindNextFile" immer doppelt auf... somit siehst Du nur jede 2. Datei...



  • stimmt.. 🙄



  • wie sieht denn eigentlich der eleganteste Weg aus, um ein Verzeichnis von einer Datei zu unterscheiden, da GetFileAttributes ja anscheindend nur für Fat funktioniert.

    Gruß
    Daniel



  • if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        ...
    

    MfG SideWinder



  • thank you

    Gruß
    Daniel



  • ich fürchte das diese Frage jetzt eher ins C++ Forum gehört, aber ich möchte auch ungern den Zusammenhang hier zerreißen.

    Meine Frage: Ich will die erkannten Dateinamen und Verzeichnisse in eine Liste Laden die ich dann Sortieren kann. Ist dies prizipiell mit Listen möglich, oder überhaupt die beste Lösung? Bei einem normalen Array hätte ich ja das Problem, dass ich das Einlesen zweimal durchführen müsste ( einmal zum Prüfen wieviele Elemente mein Array braucht und dann nochmal um die Werte einzutragen ).

    Gruß
    Daniel

    PS: Hab kein Beispiel gefunden.



  • DanielN schrieb:

    Meine Frage: Ich will die erkannten Dateinamen und Verzeichnisse in eine Liste Laden die ich dann Sortieren kann. Ist dies prizipiell mit Listen möglich,

    Ja, ist es, wobei ich eher Container mit wahlfreiem Zugriff vorziehen würde (vector/deque)

    oder überhaupt die beste Lösung?

    Beste Lösung wäre ein (multi)set, das sortiert die Elemente direkt beim Einfügen.

    PS: Aber egal welchen Container du verwendest - pack' dort lieber string's (bzw. wstring's) rein als TCHAR*.



  • bei multi(set) kann ich dir leider nicht mehr folgen. Gibt es denn irgendwo im Netz ein Dokument mit Beispielen das den Umgang mit <vectoren> praktisch erklärt? Mir zeigt sich nicht der Sinn, wenn ich doch alles wie bei Arrays machen muss, sprich keine Erleichterung zu sehen ist.

    Aber wie gesagt ich weiss nicht was du mit multi set meinst.

    Gruß
    Daniel



  • Versuch's mal mit www.cppreference.com (oder in der MSDN).

    Vectoren kannst du tatsächlich fast wie Arrays verwenden, allerdings können sie sich zur Laufzeit vergrößern, wenn sie mehr Platz brauchen:

    vector<wstring> dir;
    while(FindNextFile(hand,&finddata) !=0) 
    {
      dir.push_back(finddata.cFileName);//vergrößert den vector
    }
    
    sort(dir.begin(),dir.end());//Sortierung
    
    for(vector<wstring>::iterator pos=dir.begin();pos!=dir.end();++pos)
      wcout<<*pos<<endl;
    

    Set und Multiset sind geordnete Container (Multiset kann doppelte Werte enthalten), die ihre Elemente automatisch in aufsteigender Reihenfolge - ergo sparst du dir das Sortieren:

    set<wstring> dir;
    while(FindNextFile(hand,&finddata) !=0) 
    {
      dir.insert(finddata.cFileName);
    }
    
    for(vector<wstring>::iterator pos=dir.begin();pos!=dir.end();++pos)
      wcout<<*pos<<endl;
    


  • Ich danke dir, aber es ist doch nun wirklich so das Intern die Vectoren wie Arrays behandelt werden oder? Damit meine ich das keine neue Datenstruktur geschaffen wurde die sich zur Laufzeit in ihrer Größe ändern kann, weil ja vectoren für große Datenmengen genauso langsam werden wie Arrays die neu definiert werden und dann die alten Werte einfach kopieren + den neuen Wert. Da ich hier eine Verzeichnisauflistung programmieren will stellt sich mir nun die Frage ob es nicht wirklich schneller geht (bei 100000 Einträgen und mehr) die Routine zweimal auszuführen und dann das Kopieren zu sparen?

    Ich werde deinen Vorschlag jetzt mal testen, weil er mindestens meine schwachen C++ Kenntnisse aufmöbelt.

    Gruß
    Daniel


Anmelden zum Antworten