FindFirstFile() Problem



  • Hallo,

    bei mir liefert FindFirstFile nur merkwürdige Teichen, die mit '@' beginnen.

    char szBuffer[MAX_PATH];
    HRESULT HRvalue = SHGetFolderPath(HWND_DESKTOP, CSIDL_PERSONAL, NULL, 0, szBuffer);  //ermiteln des Dateipfades zu 'eigene Dateien'
        if(HRvalue == 0)
        {
    	string sPath = string(szBuffer);
    	MessageBox(HWND_DESKTOP, LPpath, "eigene Dateien", MB_ICONINFORMATION |MB_OK);
    
    	sPath.append( "\\trace.????????.txt");
    	string ToReplace = "\\";
    	sPath.replace(sPath.find(ToReplace),ToReplace.size(),"/");
    	cout << "Suche nach: " << sPath << endl;
    	LPCSTR fFirstFile = sPath.c_str();
    	HANDLE fHandle;
    	WIN32_FIND_DATA wfd;
    	fHandle = FindFirstFile(fFirstFile, &wfd);
    
    	do 
    	{ 
       	// Eintrag nur behandeln, wenn es nicht . oder .. ist (werden nur bei Unterverzeichnissen mit zurückgeliefert) 
        	// hier könnte man z.B. auch mit lstrcmp auf . und .. vergleichen, was allerdings nicht ganz so effizient ist 
        	    if (!( (wfd.cFileName[0]=='.') && ( (wfd.cFileName[1]=='.' && wfd.cFileName[2]==0) || wfd.cFileName[1]==0 ) )) 
        	    { 
            		if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
            		{ 
                	    MessageBox(0,wfd.cFileName,"Folgendes Verzeichnis wurde gefunden:",0); 
                	    // Datei ist keine, sondern ein Verzeichnis... 
                	    // Hier könnte man dasselbe nochmal machen, um auch die 
                	    // Unterverzeichnisse zu scannen ;-) 
            		} 
            	else 
            		{ 
                	    MessageBox(0,wfd.cFileName,"Folgende Datei gefunden:",0); 
            		} 
       	    } 
    	} 
    	while (FindNextFile(fHandle,&wfd)); 
    	FindClose(fHandle);
    	if(fHandle == INVALID_HANDLE_VALUE)
    	cout << "Fehler! Konte keine Datei finden!" << endl;
    	string sFilename =string(wfd.cFileName);
    
    	cout << "Dateiname: " << sFilename << endl;
    
        }
        else
        {
    	MessageBox(HWND_DESKTOP, "Failed to get location!", "eigene Dateien", MB_ICONERROR | MB_OK);
    	cout << szBuffer << endl;
        }
    

    Ziel: Ich will Textdateien finden und öffnen, die 'trace.xxxxxxxx.txt' heißen, wobei die x Zahlen sind. Es befinden sich auch .000 Dateien in dem Ordner - sonst nichts.

    Wie man sieht, ermitle ich erst den Dateipfad von 'eigene Dateien', wandle das Ergebnis in einen string um, bearbeite ihn und ersetze die '\' gegen '/'. Dann wandle ich ihn wieder in einen c-String um und übergebe ihn an die Funktion FindFirstFile().
    Es öffnet sich eine MessageBox und teilt mir mit: Folgende Datei gefunden:
    |€?w -- wobei das Fragezeichen umgekehrt ist.
    Das DosFenster meldet dann Fehler keine Datei gefunden!
    Dateiname: |Crw (wobei das C einen Haken unten hat und das r ein kleiner Winkel ist).
    Process exited normally.

    Ich vermute, dass es die Form des C-Strings ist, die ich verwende, und er zwar irgendwo sucht, bloß nicht da, wo er soll.

    Hat ein Profi eine Lösunug?

    Jens 😕



  • xenayoo schrieb:

    bei mir liefert FindFirstFile nur merkwürdige Teichen, die mit '@' beginnen.

    FindFirstFile liefert dir die Information, dass gar nichts gefunden wurde. Das prüfst du aber nicht (bzw. zu spät), sondern fängst mit der Ausgabe an. Kein Wunder, dass da Mist angezeigt wird.

    xenayoo schrieb:

    ersetze die '\' gegen '/'.

    Nicht "die". Du ersetzt den ersten Backslash (und nur diesen) durch einen normalen Schrägstrich. Wozu eigentlich?



  • Hallo MFK,

    ich prüfe zwar erst spät, ob das Handle gültig ist. Das der Fehler gemeldet wird, sehe ich selber, abe: Wenn er da sucht, wo er soll, dann gibt es dort .txt dateien und .000 dateien. Er müsste also etwas finden. Frage ist: Wo sucht er - falls er nicht da sucht, wo er soll? Und Warum? Der Pfad sieht für mich einwandfrei aus.

    if(fHandle == INVALID_HANDLE_VALUE)
        cout << "Fehler! Konnte keine Datei finden!" << endl;
        string sFilename =string(wfd.cFileName);
    
        cout << "Dateiname: " << sFilename << endl;
    

    Meine Vermutung ist, dass er nicht da sucht, wo er suchen soll, obwohl ich jetzt mit den strings rauf und runter gesucht habe und keine andere Lösung als die verwendete gefunden habe. Irgendwo stekct der Teufel im Detail.

    Die Backslashersetzung habe ich vorgenommen, da ich in c' auch damit schon mal Probleme hatte. Hat aber nichts am Ergebnis geändert. Es handelt sich hierbei schlicht um den Versuch, das Problem zu lösen.

    Jens



  • xenayoo schrieb:

    Wo sucht er - falls er nicht da sucht, wo er soll? Und Warum?

    Meine Kristallkugel ist in der Werkstatt.

    Lass dir nach FindFirstFile den Rückgabewert von GetLastError ausgeben.

    Und zeig mal die Ausgabe hinter "Suche nach: " sowie den vollständigen Pfad zu einer deiner gesuchten Dateien.



  • Hallo MFK,

    mit GetLastError() hab ich mich noch nicht befasst - d.h. ich steh naoch auf Kriegsfuß damit. Klingt zwar irgendwie einfach, doch wenn ich Beispiele sehe, muß ich immer nen Berg Variablen deklarieren....
    oder reicht ein

    int i = GetLastError();
    

    ?

    Ich habe jetzt die Replacefunktion wieder entfernt, nachdem ich in MSDN etwas über die Namenskonventionen gelesen habe. Da steht, dass FindFirstFile relativ zum aktuellen Verzeichnis ducht, falls nicht explizit ein "C:\" am Anfang steht.
    Seit dem sagt das Programm nicht mehr in der MessageBox "Datei gefunden" sondern "Folgendes Verzeichnis wurde gefunden". <kein name>

    Der Pfad ist:
    C:\Dokumente und Einstellungen\<meinName>\Eigene Dateien\*.txt
    Jens



  • xenayoo schrieb:

    mit GetLastError() hab ich mich noch nicht befasst - d.h. ich steh naoch auf Kriegsfuß damit.

    Kannst du den Debugger bedienen?

    xenayoo schrieb:

    Seit dem sagt das Programm nicht mehr in der MessageBox "Datei gefunden" sondern "Folgendes Verzeichnis wurde gefunden". <kein name>

    Du prüfst das Ergebnis von FindFirstFile immer noch nicht, stimmts?

    Es ist sinnlos, sich Suchergebnisse anzeigen zu lassen, wenn die Suche erfolglos war. Wenn FindFirstFile INVALID_HANDLE_VALUE zurückgibt, ist der Inhalt der WIN32_FIND_DATA-Struktur undefiniert.

    xenayoo schrieb:

    Der Pfad ist:
    C:\Dokumente und Einstellungen\<meinName>\Eigene Dateien\*.txt

    Copy&Paste bitte, nicht sinngemäß abschreiben. Sonst ist das witzlos. Wenn da ein Fehler im Pfad steckt, den du nicht siehst, korrigierst du ihn vermutlich beim Abschreiben.



  • Hallo MFK,

    hab jetzt mal versucht, aus der MSDN die Funktion aus dem Beispiel für GetLastError() einzubauen -> ErrorExit()

    Da meckert der Kompiler über die MS-Sonderfunktion Namens STringCchPrintf(). Den notwendigen Header strsafe.h hab ich nicht. So langsam kotzt mich die Win32API an.........

    Leider habe ich keine einfache Variante gefunden, die das Ergebnis einfach ins Dos-Fenster streamt...

    Was den Dateipfad angeht: Der wird automatisch ermittelt und beinhaltet "\" als Trennzeichen. Durch deinen Hinweis habe ich mir den Pfad aber mal genau angesehen und du hast natürlich völlig recht. Jetzt funktioniert es. Jetzt habe ich also einen Filenamen und ein Handle.

    Nun muss ich also eine Datei öffnen und parsen..... Auf zur nächsten Baustelle...

    Jens



  • Wenn Dich die WinApi ankotzt hast Du folgende Möglichkeiten:
    - nicht benutzen
    - richtige Werkzeuge nehmen. z.B. VS das mit den passenden Libs für
    die Beispiele aus der MSDN daher kommt.
    - schlicht und ergreifend die Beispiele verstehen und für Deine
    Entwicklungswerkzeuge und die dazugehörigen Bibliotheken anpassen.

    Psyschologisch entlastent ist es natürlich MS und die von MS verbrochenen APIs für alles was Du nicht verstehst und kannst als Sündenbock zunehmen.



  • GetLastError ist wirklich nicht schwer zu bedienen. Mach es nicht unnötig kompliziert. Deklariere eine DWORD-Variable, weise ihr die Rückgabe von GetLastError zu und gib den Wert aus bzw. schau ihn dir mit dem Debugger an. Den Error-Code kannst du dann in der Fehlerliste von Microsoft suchen.

    Der Debugger ist übrigens ein Werkzeug, mit dem du dich unbedingt vertraut machen sollest. Lieber früher als später. Dann entfällt das Rätselraten, was denn wohl zur Laufzeit passiert - du kannst es dir einfach live anschauen. 🙂



  • noergel schrieb:

    Wenn Dich die WinApi ankotzt hast Du folgende Möglichkeiten:
    - nicht benutzen
    - richtige Werkzeuge nehmen. z.B. VS das mit den passenden Libs für
    die Beispiele aus der MSDN daher kommt.
    - schlicht und ergreifend die Beispiele verstehen und für Deine
    Entwicklungswerkzeuge und die dazugehörigen Bibliotheken anpassen.

    Psyschologisch entlastent ist es natürlich MS und die von MS verbrochenen APIs für alles was Du nicht verstehst und kannst als Sündenbock zunehmen.

    Es gibt genug Beispiele, wie es besser geht. Nicht jeder ist bereit, für ein kleines Projekt die überzogenen Kosten für eine Entwicklungsumgebung auszugeben. Natürlich kann man auch die 'kostenlosen' Express-Editions nehmen, aber eigentlich nur für den Privatbedarf.
    Unabhängig davon gibt es geug Dinge, die auch VS nicht besser macht als andere Entwicklungsumgebungen.
    MSDN wäre eine feine Sache - wenn dies durchdacht durchgezogen worden wäre. Aber Denken schaut man sich bei Microsoft bei anderen ab und was man nicht versteht, wird mit imensem Speicherbedarf zusammengemurkst.
    Man kann natürlich auch zum MS-Jünger werden und jeden Scheiß gut finden, den sie verzapfen.... 😉 Andere Hersteller legen ihre Entwicklungsumgebungen KOSTENLOS ihren OS bei..... noch Fragen?

    @_matze: Danke, ich werd es mal ausprobieren....



  • Wenn Du mit der MSDN nicht zurechtkommst und die Beschreibungen und Beispiele nicht recht verstehst,ist das erstmal Dein Problem.
    Was übrigens an der MSDN nicht durchdacht ist, erschließt sich mir nicht:
    http://msdn.microsoft.com/en-us/library/windows/desktop/ff818516%28v=vs.85%29.aspx

    Das ist übrigens der Artikel zu FindFirstFile:
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418%28v=vs.85%29.aspx

    Die "noch Fragen" von einem "MS-Jünger":

    Warum nimmst Du dann nicht das andere Os mit beigelegter Entwicklungsumgebung?
    Warum willst Du ein Programm für ein Dir verhasstes BS entwickeln?

    Und warum, falls Du gezwungen bist für das böse Windows zu entwickeln, nimmst Du nicht Qt?



  • Hallo suchst du sowas in der Art?

    hFind = FindFirstFile("C:\\*" , &FindFileData); ]/cpp]
    Da müsstest du halt noch den Pfad anpassen.
    
    [cpp]
            if ( ! str.find("trace") && str[str.length()-1] == 't' && str[str.length()-2] == 'x'
            && str[str.length()-3] == 't')
    

    Ob man sich das mit dem str[str.length()- ... ]]; sparen kann weiss ich nicht vielleicht kann man das hier auch einbauen vielleicht gibts da eine passende Wildcard aber ka ich will auch gerade nicht in der MSDN nachlesen.^^

    hFind = FindFirstFile("C:\\*" , &FindFileData);
    
    #include <iostream>
    #include <vector>
    #include <windows>
    using namespace std;
    
    void FillStorage( vector<string> & Storage )
    {
    WIN32_FIND_DATA FindFileData;
    ZeroMemory( & FindFileData,sizeof(FindFileData));
    HANDLE hFind;
    string str;
    
       hFind = FindFirstFile("C:\\*" , &FindFileData);
    
       while ( FindNextFile( hFind , &FindFileData) )
       {
            str = FindFileData.cFileName ;
    
            if ( ! str.find("trace") && str[str.length()-1] == 't' && str[str.length()-2] == 'x'
            && str[str.length()-3] == 't')
            {
               Storage.push_back(str);
            }
       }
       FindClose(hFind);
    }
    
    int main(int argc, char* argv[])
    {
    
    vector<string>Storage;
    
    FillStorage(  Storage );
    
       for(unsigned i=0;i<Storage.size();i++)
       {
            cout<<Storage[i]<<endl;
       }
    
    system("PAUSE");
    return 0;
    }
    //---------------------------------------------------------------------------
    

Anmelden zum Antworten