Festplatte katalogisieren
-
Außerdem solltest du statt der freien Funktionen "Read", "Child" und "Suchen" besser Klassenmethoden erstellen. Dann benötigst du auch nicht immer den Zugriff mittels "Form1->" (und wenn schon dann übergib diesen als Parameter!!!)
Desweiteren sollten Funktionen ohne Parameter in C++ einfach als "()" und NICHT als "(void)" daklariert werden.
Am besten ist, du liest dich noch mal in die objektorientierte Programmierung ein. Evtl. erst mal ein einfacheres Programm programmieren, denn wie Linnea schon geschrieben hat, ohne Rekursion wirst du die Ordner und Dateien nicht korrekt auslesen können (und dazu gehört u.a. das Wissen umd die Verwendung von Funktionsparametern).
Sorry, ich weiß, jeder Anfang ist schwer, aber so ein Code-Gefrickel fördert nicht das Programmieren, sondern erzeugt mehr und mehr Frust (so wie ich deine Kommentare deute, ist es bei dir schon soweit).
-
Gab es mit FindFirst/FindNext nicht Probleme in Verbindung mit einer rekursiven Funktion? Ich meine hier mal so was gelesen zu haben...
Wie auch immer, ich hab das mittels FindFirst/FindNext in Verbindung mit zwei TStirngList-Instanzen gelöst. Beim Einlesen mit FindFirst/FindNext prüfe ich ob, es eine Datei, oder ein Verzeichnis ist. Dateien kommen in die eine TStringList, Verzeichnisse in die andere TStringList. In der TStringList für Verzeichnisse trage ich das / die Startverzeichnis(se) ein. Wann immer ein weiteres Verzeichnis bei der Suche gefunden wird, wird es in diese Liste eingetragen. Wenn ein Verzeichnis komplett abgearbeitet ist, wird es aus dieser Liste gelöscht. Sobald diese Liste leer ist, ist die Suche komplett abgeschlossen.
-
Th69 schrieb:
Desweiteren sollten Funktionen ohne Parameter in C++ einfach als "()" und NICHT als "(void)" daklariert werden.
Das hab ich noch nie gehört. Ich hab gelesen, dass das bei C++ absolut keinen Unterschied macht. Bei C hingegen schon.
-
bei einem "()" statt "(void)" meckert er rum. ich weiß nicht was genau aber er will umbedingt, dass da etwas steht, sonst hat er "zu wenige Parameter".
Ja als Klassenmember... ja das wäre schlau gewesen mach ich gleich.
Rekursion, hört sich kompliziert an aber ich guck mirs mal an.
ich halt euch auf dem laufenden
-
Hallo
Fakt ist : In C geht nur (void).
In C++ kann man (void) schreiben. Ist aber veraltet, man sollte immer () schreiben.Wenn du in C++ "Fehler" bei () bekommst machst du irgendetwas falsch.
bis bald
akari
-
Bei Wikipedia habe ich folgendes zur Methode rekursiver Implementation ( :p ) gefunden:
void fnTraverse( char* pString ) { if( *pString == 0x0 ) return; else // z. B. Buchstabe für Buchst. ausgeben fnTraverse( ++pString ); }
++pString
was zur hölle soll denn das (bringen)?
-
Hallo
Das gehört zum Thema Zeigerarithmetik. Der Wert von pString wird um eins erhöht und als Argument an den nächsten Aufruf von fnTraverse übergeben. Dadurch zeigt pString beim nächsten Aufruf auf das nächste Zeichen in der Zeichenkette.
bis bald
akari
-
Vielleicht kannst du das gebrauchen:
void TextFileSearch(String Path,TStringList *files) { Path=IncludeTrailingBackslash(Path); HANDLE FH; WIN32_FIND_DATA fdat; String Ffile=Path+"\\*"; FH=FindFirstFile(Ffile.c_str(),&fdat); while (FindNextFile(FH,&fdat)) { Ffile=fdat.cFileName; if (fdat.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && Ffile != ".." && Ffile !=".") { TextFileSearch(Path+fdat.cFileName,files); } else if (ExtractFileExt(fdat.cFileName)==".txt") { files->Add(Path+fdat.cFileName); } } FindClose(FH); }
-
void __fastcall TDirListForm::Search(AnsiString Root) { TStringList *Dirs=new TStringList(); TSearchRec f; int FFRes; AnsiString Verz; SB->SimpleText="Suche in: " + Root; if (Root[Root.Length()]=='\\') Verz=Root+"*.*"; else Verz=Root+"\\*.*"; FFRes=FindFirst(Verz,0x10,f); /* Verzeichnisse suchen */ if (FFRes==0) { while (FFRes==0) { if ((f.Attr&0x10)==0x10) { ;//Dir if (Subdirs->Checked) if (f.Name[1]!='.') Dirs->Add(f.Name); } FFRes=FindNext(f); } FindClose(f); } if (Root[Root.Length()]=='\\') Verz=Root + Edit1->Text; else Verz=Root + "\\" + Edit1->Text; FFRes=FindFirst(Verz,0x20,f); /* Dateien suchen */ if (FFRes==0) { if (PathMode->ItemIndex==1) { if (DirList->Lines->Count>0) DirList->Lines->Add(""); DirList->Lines->Add(Root); DirList->Lines->Add(""); } while (FFRes==0) { if ((f.Attr&0x10)!=0x10) { ;//File if (PathMode->ItemIndex==2) { if (Root[Root.Length()]=='\\') DirList->Lines->Add(Root+f.Name); else DirList->Lines->Add(Root+"\\"+f.Name); } else { DirList->Lines->Add(f.Name); } FileAnz->Caption=FileAnz->Caption.ToInt()+1; } FFRes=FindNext(f); } FindClose(f); } for (int i=0;i<Dirs->Count;i++) { Update(); if (Root[Root.Length()]=='\\') Search(Root+Dirs->Strings[i]); else Search(Root+"\\"+Dirs->Strings[i]); } delete Dirs; } void __fastcall TDirListForm::ListClick(TObject *Sender) { if (Clear->Checked) { DirList->Clear(); FileAnz->Caption=0; } Search(DOLE->Directory); SB->SimpleText=""; }
FileAnz ist ein TLabel
DOLE ist eine eigene Kompo - liefert einen kompletten Pfad als Start für Suche
DirList ist ein TMemo
PathMode ist eine Optionsauswahl (NoPath Grouped FullPath = 0 .. 2)
SubDirst ist ein OptionskästchenGruss
Frank
-
Vielen Dank für die Mühe aber:
1. Was ist SB (SimpleText ???)
2. Es kommt SOFORT beim starten zum stack overflow, hab ichs falsch eingebaut ???
-
Hallo
Der Stackoverflow deutet darauf hin das die Rekursionstiefe zu hoch ist. Sprich du hast zu viele verschachtelte Unterverzeichnisse, die sich dadurch immer wieder aufrufende Search-Funktion belegt dann schnell den ganzen Stack und das Programm muß beendet werden.
Falls das der Grund ist, must du die rekursive Funktion in eine iterative umschreiben.bis bald
akari
-
Bevor ich jetzt dran rumwerkel mach ichs noch mal selbst, nicht weil ich zu blöd für wäre, aber es ist doch der sinn das ichs lerne selbst zu schreiben, außerdem fühle ich micht dann nicht zufrieden.
EDIT: Ich werde mich aber an dem Code orientieren
aber was ist noch die Komponente SB ?
-
void MAINPROCESSVOID(void) { ofstream Katalog; Katalog.open(Katalog_on_Drive.c_str(),ios::binary); SearchFin = false; breaker = 0; Form1->DIB->ItemIndex = 0; Form1->FLB->ItemIndex = 0; Folder4 = 0; while (SearchFin == false && breaker == 0) { Form1->DIB->ItemIndex = Form1->DIB->ItemIndex+1; Form1->Gauge1->Progress++; Form1->Refresh(); Sleep(1); Folder4++; Form1->DIB->OpenCurrent(); if (true) { Form1->FLB->Directory = Form1->DIB->Directory; } Form1->DIB->ItemIndex = Form1->DIB->ItemIndex+1; Form1->FLB->ItemIndex = 0; std::string Name_Zeile = ""; // MessageBox(NULL,"Pause","Debug Mode",MB_OK); if (Form1->FLB->Items->Count > 0) { while (Form1->FLB->ItemIndex+1 < Form1->FLB->Items->Count) { // MessageBox(NULL,FLB->FileName.SubString(FLB->FileName.Length()-3,4).c_str(),"Debug Mode",MB_OK); if (Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".mp3" || Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".wav" || Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".avi" || Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".wma") { // MessageBox(NULL,"True","Debug Mode",MB_OK); Name_Zeile = Form1->FLB->FileName.c_str(); Name_Zeile += "\n"; Katalog << Name_Zeile; } Form1->FLB->ItemIndex = Form1->FLB->ItemIndex+1; } if (Form1->FLB->ItemIndex+1 == Form1->FLB->Items->Count) { Form1->Gauge2->Progress = 0; Form1->Gauge2->MaxValue = Form1->FLB->Items->Count+1; if (Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".mp3" || Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".wav" || Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".avi" || Form1->FLB->FileName.SubString(Form1->FLB->FileName.Length()-3,4)==".wma") { // MessageBox(NULL,"True","Debug Mode",MB_OK); Name_Zeile = Form1->FLB->FileName.c_str(); Name_Zeile += "\n"; Katalog << Name_Zeile; Form1->Gauge2->Progress++; } } } // MessageBox(NULL,"Pause","Debug Mode",MB_OK); if (Form1->DIB->ItemIndex+1 == Form1->DIB->Items->Count) { Form1->DIB->Directory = destidir.c_str(); int i = 0; while (i < Folder4) { Form1->DIB->ItemIndex++; // MessageBox(NULL,"Pause","Debug Mode",MB_OK); i++; } //DIB->OpenCurrent(); } if (Form1->DIB->ItemIndex+1 == Form1->DIB->Items->Count) { Form1->Gauge1->Progress = 0; Form1->Gauge2->Progress = 0; SearchFin = true; MessageBox(NULL,"Fertig Katalog erfolgreich erstellt","Fertig",MB_OK); } } Katalog.close(); /* ifstream test; test.open("C:\\Kat.katalog"); std::string test2; std::getline(test,test2); MessageBox(NULL,test2.c_str(),"Debug Mode",MB_OK); */ }
Nun damit kann ich wenigstens schon mal bis zu einem Unterordner katalogisieren.
Ich mache Fortschritte, auch wenn ich hier keine Rekursion benutzt haben
und FindNext könnte auch hilfreich sein, ich bau das mal ein.EDIT: bitte sagt nix über GetFileExtansion
-
SB ist eine Statusbar! hatte ich wohl vergessen anzugeben.
Ein Stack- Overflow ist bei mir auch über >10 Ebenen noch nicht passiert???
Gruss
frank
-
Ja ?
Könntest du evtl das Projekt irgendwo uploaden ?
Solangsam verliere ich wirklich die Gedult.
mit folgendem Programm geht es nurbis zu einem bestimmten Komplexitätsgrad.
(mehre unterordner in mehreren unterordner ist zu viel)
Ich poste es einfach mal://--------------------------------------------------------------------------- #include <vcl.h> #include <string> #include <sstream> #pragma hdrstop #include "Katalogia.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "DirOutln" #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- void TForm1::READ(void) { FLB->Directory = DLB->Directory; RICH->Lines = FLB->Items; // ShowMessage(RICH->Text.c_str()); KomponentenNamen += RICH->Text.c_str(); } void TForm1::Child(String Dir, int Childcount) // beide Parameter nicht mehr in Gebrauch { DLB->Directory = Dir.c_str(); if (readmain == 0) { readmain = 1; READ(); } DLB->ItemIndex++; DLB->OpenCurrent(); FLB->Directory = DLB->Directory; READ(); int Child_Of_Child = DLB->Items->Count - (DLB->ItemIndex+1); Childs_have_been_read++; if (Child_Of_Child == 1) { DLB->ItemIndex++; Child(DLB->Directory, Child_Of_Child); } else if (Child_Of_Child > 1) // Ich unterscheide zwischen der Unterordnerzahl { Sub_Child = Childs_have_been_read; DLB->ItemIndex++; Multi_Child(DLB->Directory); } if (Child_Of_Child == 0) { int ReadChilds = 0; while (ReadChilds < Childs_have_been_read) { ReadChilds++; DLB->ItemIndex--; } DLB->OpenCurrent(); Childs_have_been_read = 0; } } void TForm1::Suchen(void) // Primärer Algorithmus { int Childreen = DLB->Items->Count - (DLB->ItemIndex); DESTICHILDCOUNT = Childreen; int i = 1; DESTINATION = DLB->Directory.c_str(); int one = 0; Sub_Child = 0; while (i < Childreen) { i++; Childs_have_been_read = 0; Current_Child++; Parent = DLB->Directory.c_str(); Child(DLB->Directory, Childs_have_been_read); int x = 0; while (x < Current_Child) { x++; DLB->ItemIndex++; } } } __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { readmain = 0; } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButton1Click(TObject *Sender) // Beginnnt hier { DOUT->Update(); RICH->Text = LEER->Text; LB->Items = LEER->Lines; DLB->Directory = DOUT->Directory; DESTICHILDCOUNT = 0; Current_Child = 0; // SCHLEIFE ! // ShowMessage("PAUSE"); Suchen(); RICH->Text = KomponentenNamen.c_str(); LB->Items = RICH->Lines; } //--------------------------------------------------------------------------- void __fastcall TForm1::DOUTChange(TObject *Sender) { DLB->Directory = DOUT->Directory; } //--------------------------------------------------------------------------- void TForm1::Multi_Child(String CHDIR2) { int i = 1; // DLB->Directory = CHDIR2; int Childreen = DLB->Items->Count - (DLB->ItemIndex); std::string go_back = DLB->Directory.c_str(); while (i < Childreen) { Childreen = DLB->Items->Count - (DLB->ItemIndex); ShowMessage(IntToStr(Childreen).c_str()); i++; DLB->OpenCurrent(); Childs_have_been_read--; Child(DLB->Directory, Childreen); std::stringstream RCtoI; RCtoI.clear(); RCtoI << Childreen; RCtoI << " und "; RCtoI << i-1; ShowMessage(RCtoI.str().c_str()); int ReadChilds = 0; while (ReadChilds < i-1) { ReadChilds++; DLB->ItemIndex--; } DLB->OpenCurrent(); int x = 0; while (x < i) { x++; DLB->ItemIndex++; } } DLB->Directory = go_back.c_str(); }
Gibt es nicht irgendwo was Fertiges ? Ich habs langsam Satt, ich kann so tiefgründig nicht denken (Kein Kommentar).
Wenn ich bei geringer Komplexität beginne hab ich nacher ein Problem weil es nicht auf höere Komplexität aufstufbar ist.
Wenn ich gleich volle Kanne ran gehe, blicke ich nach 20 min nicht mehr durch meinen eigenen Code durch.Ach und wenn eine Funktion mir localen variablen in sich selbst aufrufe und gegeneinander, werden die Variablen dann neu angelegt oder überschrieben ?
(hier Child und Multi_Child ineinander verzweigt) Oder muss ich arrays anlegen ?Aber so langsam machts mir die lust kaputt und ich hör damit lieber auf und hoffe auf ein Wunder :p
-
Kannst Du Projekte vom BCB 4.0 problemlos einlesen?
Dann kann ich Dir das Projekt mailen.Schicke einfach eine Mail an die Adresse mit "DerAltenburger..." - die genaue Adresse steht auf meiner HP.
Gruss
Frank
-
Hallo,
ich weis nicht, ob das Thema nach aller der langen Zeit noch aktuell ist, aber auch ich möchte einen Code Schreiben, der eine Festplatte Katalogisiert.
Ich steige gerade in C ein und werde auf C++ weiter aufbauen.
Mal sehen, ob das ganze auch schon ab C lösbar ist.Mike
-
Ja sicherlich!
Momentan mache ich das Ganze aber schon etwas anders, als hier beschrieben.
Ich mache das momentan so (möglicherweise nicht so effizient, aber auch möglich):- 2 Listen anlegen (eine für Ordner und eine für Dateien)
- Das Anfangsverzeichnis der Ordnerliste hinzufügen
- Odernerliste durcharbeiten- Erstes Verzeichnis als aktuelles übernehmen und aus Liste entfernen (oder Index der Liste weitersetzen, wenn man die Verzeichnisse behalten will)
- Nach Verzeichnissen im aktuellen Verzeichnis suchen und Dateiliste hinzufügen
- Wiederholen bis Ordnelist leer (oder Index = Listengröße)- Bedarfsweise die Listen sortieren.
PS: Siehe Signatur 2. Teil :p
-
Eine Verzeichnisstruktur gleicht einem binären Baum, deren Struktur verzweigt und deren Tiefe nicht vorgegeben ist.
In solchen Fällen werden immer rekursive Funktionen oder Prozeduren programmiert.
Mann muss nur den richtigen Algorithmus entwickeln, dann klappt es auch. Also nicht einfach drauf los programmieren, sondern erst mal überlegen und die richtige Vorgehensweise ausarbeiten.Der Denkansatz ist, das man einen Baum untersucht, und von oben nach unten in die Tiefe geht. Die Bedingung ist, wenn kein Ordner mehr vorhanden ist, dann katalogisiere den Inhalt des aktuellen Ordners.
Also in der untersten Ebene anfangen und nach oben arbeiten.
Wo speicherst Du den Inhalt denn hin?
Machst Du ein Textfile, oder Speicherst Du in eine Datenbank?
Bist Du nur am Katlogisierungsproblem, oder denkst Du auch schon über eine Synchronisierung der Verzeichnisstruktur mit dem Katalog nach?Mike
-
Mike Dreamer schrieb:
Eine Verzeichnisstruktur gleicht einem binären Baum, deren Struktur verzweigt und deren Tiefe nicht vorgegeben ist.
Nur, dass es kein binärer Baum ist, da beliebig viele Kindknoten auftreten können.