findfirst, findnext



  • Hallöchen, Popöchen!

    Ich möchte durch findfirst und findnext einen ordner komplett durchsuchen. alle gefundenen dateien werden per MessageDlg ausgegeben. Soweit funktioniert das auch, nur leider werden häufig bestimmte Dateien doppelt und dreifach gefunden (in nur einem Ordner), was heißt, dass anscheinend findnext manchmal wieder zurückgesetzt wird oder was weiß ich, hier mein Code:

    AnsiString Dir;
        struct ffblk ffblk;
        int i = 0;
        while( i < extCount )
        {
            Dir = aDir + "\\" + extList->Strings[ i ];
            int done;
            done = findfirst( Dir.c_str( ),&ffblk, attrib );
            while( done == 0 )
            {
                AnsiString tmp = aDir + "\\" + ffblk.ff_name;
                done = findnext( &ffblk );
                MessageDlg( aDir + "\\" + ffblk.ff_name, mtConfirmation, TMsgDlgButtons( ) << mbOK, 0 );
                Application->ProcessMessages( );
            }
            i++;
        }
    

    Tipp: extList->Strings enthält alle zu durchsuchenden Dateiendungen, daran liegt der Fehler nicht!



  • Dass die letzte Datei in einem Schleifendurchlauf doppelt angezeigt wird ist ja klar. (weil du done nicht prüfst) Warum aber dreifach verstehe ich auch nicht.



  • klar prüfe ich dann in der while-abfrage mittels done == 0!?



  • falsch!

    while ist eine anfangsgeprüfte schleife

    while( done == 0 )
    {
      AnsiString tmp = aDir + "\\" + ffblk.ff_name;
      done = findnext( &ffblk );
    
      MessageDlg( aDir + "\\" + ffblk.ff_name, mtConfirmation, TMsgDlgButtons( ) << mbOK, 0 );
    
      Application->ProcessMessages( );
    }
    

    wenn findnext null liefert, springt das programm wieder zum anfang der schleife und prüft dort die bedingung ab (done == 0?). das ist erfolgreich. liefert findnext dann aber einen anderen wert schlägt die prüfung fehl und in ffblk steht noch immer der wert der vorherigen abfrage. ergo bekommst du doppelte ergebnisse! du solltest hier eine endgeprüfte schleife (do - while) verwenden!

    der fehler das manche dateien 3fach auftauchen, liegt einfach daran, dass wahrscheinlich bestimmte suchwerte nicht gefunden werden und da du die ffblk struktur ausserhalb der schleifen erzeugst, existieren die vorherigen suchwerte beim nicht finden von bestimmten dateiendungen immer noch?

    frage: warum verwendest du nicht FindFirst, FindNext und FindClose und stattdessen dieses veraltete zeugs?

    TSearchRec dirinfo;
    
    AnsiString pfad = ExtractFilePath(Application->ExeName);
    
    // alle txt-dateien löschen im verzeichnis der exe
    if (!FindFirst(pfad + *.txt", faAnyFile, dirinfo))
      DeleteFile(AnsiString(pfad + dirinfo.Name));
    
    // funktioniert hier, da die funktion im schleifen-kopf aufgerufen wird!
    while (!FindNext(dirinfo))
      DeleteFile(AnsiString(pfad + dirinfo.Name));
    
    FindClose(dirinfo);
    


  • klar prüfe ich dann in der while-abfrage mittels done == 0!?

    Aber nicht zwischen findnext und MessageDlg!

    Der erste gefundene Eintrag wird garnicht, der letzte doppelt angezeigt.

    Die Zeile mit MessageDlg sollte an den Anfang der while-Schleife.

    [ Dieser Beitrag wurde am 06.03.2003 um 17:14 Uhr von Geo editiert. ]



  • Schaut 'mal bei

    "Finfirst/next->Unterverzeichnisse" von <Gast>

    da war das Thema gerade dran!!!

    (ist 'n paar Eintraege vorher gewesen!!!) 😉

    PS: Ab und zu die vorhandenen Beitraege lesen!!! 😃

    [ Dieser Beitrag wurde am 06.03.2003 um 18:53 Uhr von DerAltenburger editiert. ]



  • Sodele, vielen Dank erstmal. Ich habe nun versucht, das ganze "modern" zu schreiben, doch jetzt kommt immer ein Fehler: Liste überschreitet das Maximum (-1742343458 oder so). Wie gesagt, vorhin ging ja alles, nur leider doppelt, und ich habe obigen Code durch den jetzigen ersetzt und der Listenüberschreitungsfehler kommt. Wo ist der im Code zu sichten?

    TSearchRec dirinfo;
        AnsiString Dir;
        int i;
        while( i < extCount )
        {
            Dir = aDir + "\\" + extList->Strings[ i ];
            if( FindFirst( Dir + "*.txt", faAnyFile, dirinfo ) == 0 )
                while( FindNext( dirinfo ) == 0 && SuchStop == 0 )
                {
                    StatusBar->Panels->Items[ 0 ]->Text = dirinfo.Name;
                    AnsiString tmp = AnsiString( Dir + dirinfo.Name );
                    findStringInFile( tmp );
                    Application->ProcessMessages( );
                }
            i++;
        }
        FindClose( dirinfo );
    


  • Falsche Schleife!!!

    do
    {
    //Verarbeizung;
    }
    while(Bedingung);

    Hat auch Sunday schon gepostet. LESEN musst Du die Tips schon; 🕶

    Meiner war ernstgemeint! 😃

    [ Dieser Beitrag wurde am 06.03.2003 um 19:57 Uhr von DerAltenburger editiert. ]



  • ok, folgender Code scheint jetzt etwas besser zu gehen, zumindest kommen die doppelten gefundenen Dateien nicht mehr so angezeigt werden, aber manchmal passiert das:

    Message: C:\Eigene Dateien\test.txt
    Message: C:\Eigene Dateien\xyz.txt
    Message: C:\Eigene Dateien\test.txt

    Es kommen also auch doppelte Einträge, nur nicht direkt hintereinander 😞 😞 😞

    TSearchRec dirinfo;
        for( int i = 0; i < extCount; i++ )
        {
            if( FindFirst( aDir + "\\" + extList->Strings[ i ], faAnyFile, dirinfo ) == 0 )
                do
                {
                    StatusBar->Panels->Items[ 0 ]->Text = AnsiString( dirinfo.Name );
                    AnsiString tmp = AnsiString( aDir + "\\" + dirinfo.Name );
                    MessageDlg( tmp, mtConfirmation, TMsgDlgButtons( ) << mbOK, 0 );
                    //findStringInFile( tmp );
                    //Application->ProcessMessages( );
                }
                while( FindNext( dirinfo ) == 0 && SuchStop == 0 );
            FindClose( dirinfo );
        }
    


  • so sollte es zum beispiel gehen:

    //---------------------------------------------------------------------------
    void __fastcall TForm1::SuchAusgabe(AnsiString FileName, AnsiString Directory)
    {
      StatusBar->Panels->Items[0]->Text = FileName;
      Application->ProcessMessages();
    
      Application->MessageBox(AnsiString(Directory + "\\" + FileName).c_str(),
                              "Hinweis", MB_OK + MB_ICONINFORMATION);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      for (int i = 0; i < extCount; i++)
      {
        TSearchRec dirinfo;
    
        // suche beginnen -> erstes element anzeigen
        if (!FindFirst(aDir + "\\" + extList->Strings[i], faAnyFile, dirinfo))
          SuchAusgabe(dirinfo.Name, aDir);
    
        // nächste treffer ausgeben
        while(!FindNext(dirinfo))
        {
          SuchAusgabe(dirinfo.Name, aDir);
    
          // wenn gesetzt, schleife abbrechen
          if (SuchStop) break;
        }
    
        FindClose(dirinfo);
    
        // diese schleife auch abbrechen
        if (SuchStop) break;
      }
    }
    //---------------------------------------------------------------------------
    

    [ Dieser Beitrag wurde am 06.03.2003 um 22:28 Uhr von Sunday editiert. ]



  • Problem: Es werden in der MessageBox auch die Ordner ohne Dateinamen angegeben.

    Also es werden sowohl "C:\Eigene Dateien" als auch zum Beispiel "C:\Eigene Dateien\datei.txr" ausgegeben. Ich will aber NUR dateien haben.



  • So, nu aber schläunigst in die Hilfe und mal nachlesen was findfirst/findnext so alles bietet. Inklusive der Parameter!

    -junix



  • Sunday, bei deinem Code passiert auch folgendes:

    Message: C:\Eigene Dateien\test.txt
    Message: C:\Eigene Dateien\xyz.txt
    Message: C:\Eigene Dateien\test.txt

    wieso?



  • Weil du noch nicht die Attribute der gefundenen Einträge prüfst.



  • Doch, faAnyFile ist es doch, also jede Datei.

    ABER ICH HABE DEN FEHLER GEFUNDEN:

    Und zwar wird jeder Ordner zweimal durchlaufen.

    Wenn ich also C:\Eigene Dateien angebe, dann werden die Dateien INNERHALB des angegebenen Suchpfads immer nur einmal (richtig!) angezeigt, bei allen anderen Ordnern und damit Unterordnern dann aber zweimal ==> KONSEQUENZ: Der Fehler liegt daran, dass in Sundays und meinem "Ex-Code" alle Unterordner zweimal durchlaufen werden. Ich kann aber nicht erkennen wo :(( : ( 😞



  • Dann solltest du Debuggen...

    -junix



  • Nur Dateien bekommst Du mit ...

    if( FindFirst( Dir + "*.txt", faAnyFile & ~faDirectory, dirinfo ) == 0 )
    


  • Frage:

    Ruft ihr die Findxxx- Funktionen in einer rekursiven Programmstruktur auf? 😕

    Das vertragen die Funktionen nicht!!! (???)(Macht Ärger bei BCB 4.0)
    - Dabei wird SearchRec- Information gestört!!! - Das koennte das Fehlverhalten erklaeren!?

    Für Rekursive Suche besser:

    - Dateinamen + Unterordner in je eigene Stringliste lesen
    - Suchschleife abschliessen
    - Fuer alle (gespeicherten) Ordnernamen Rekursion rufen!

    Bei Rekursion innerhalb der Suchschleife wird Info gestoert: Nach Rueckkehr aus Rekursion ist Searchrec falsch belegt! 😮


Anmelden zum Antworten