Dateien via Parameter löschen
-
Hallo.
Ich habe mal wieder ein kleines Problem, zu dem ich einfach keinen Syntax finde.
Die Aufgabe ist folgende: Ich soll ein Programm schreiben, welches über die Konsoleneingabe mit 2 Parametern aufgerufen werden soll.
Parameter 1 ist das Verzeichnis
Parameter 2 ist eine Zahl, die das Alter in Tagen darstelltAlle Dateien im Verzeichnis, die älter sind als Parameter 2, sollen ohne rücksicht auf den Schreibschutz gelöscht werden.
bisher sieht meine Code-Überlegung so aus:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> int main (int argc,char*argv[]) { char* verzeichnis; int toleranzalter; int heute; int dateialter heute = localtime(time(NULL)); // Aktuelle Zeit ermitteln verzeichnis = argv[1]; // Verzeichnisname wird aus erstem Parameterwert ausgelesen toleranzalter = now() - argv[2]; // Alter der Datei (in Tagen) wird aus zweitem Parameterwert ausgelesen toleranzalter = heute - alter*24*3600; // Alter in Tagen wird errechnet dateialter = ?alter der datei?; // Dummy zum Auslesen des Dateialters (Vorzugsweise in Tagen) chmod(datei) = ?777?; // Dummy zum aufheben des Schreibschutzes if (dateialter < toleranzalter) remove(datei); return 0; }
Noch ist keine Funktion dabei, die das Verzeichnis nach Dateien durchsucht, ich mache das erstmal für eine einzelne Datei. Die Dummys stehen für das, wozu ich noch garkeine Idee habe. Leider haben wir in der Berufsschule bisher nur C, so dass ich nicht weiß, ob das Ganze mit einer anderen Programmiersprache vielleicht besser zu lösen ist, da C ja nun auch nicht so aktuell ist
Fakt ist: es soll auf der Konsolenebene bleiben und sich von selbst wieder schließen, so dass es eine einfache, schnelle eingabe ermöglicht.
Kann jemand weiterhelfen ... ?
-
Erstens: Die main() ist schon falsch - erlaubt sind "int main(void)" und "int main(int argc,char*argv[])", aber keine Zwischenvarianten. (d.h. die Parameternamen im zweiten Fall sind beliebig).
Zweitens: Die Argumente in argv werden in String-Form übergeben - da mußt du das Datum erst manuell in etwas verwertbares (z.B. ein 'struct tm') umwandeln.
Drittens: Auflisten von Dateien eines Verzeichnisses und Zugriff auf Dateiattribute (Erstellungsdatum o.ä.) liegen nicht im Standard - auf welchem System soll dein Programm denn laufen?
-
CStoll schrieb:
Erstens: Die main() ist schon falsch - erlaubt sind "int main(void)" und "int main(int argc,char*argv[])", aber keine Zwischenvarianten. (d.h. die Parameternamen im zweiten Fall sind beliebig).
Alles klar, wurde korregiert.
CStoll schrieb:
Zweitens: Die Argumente in argv werden in String-Form übergeben - da mußt du das Datum erst manuell in etwas verwertbares (z.B. ein 'struct tm') umwandeln.
Das klingt schonmal unschön. Aber eigentlich würde der Integerwert der vergangenen Tage/Sekunden ja reichen als Datumsformat. Seit dem 01.01.1900 halt. Damit könnte man problemlos rechnen.
CStoll schrieb:
Drittens: Auflisten von Dateien eines Verzeichnisses und Zugriff auf Dateiattribute (Erstellungsdatum o.ä.) liegen nicht im Standard - auf welchem System soll dein Programm denn laufen?
Geplant ist es erstmal auf XP Professional. Ich dachte mir schon, dass das kein simpler Standard sein wird. Unter VBA wär das wohl um einiges einfacher gewesen, nur da hätte ich keine Ahnung, wie ich das ganze mit Parametern realisiere usw. Hm ... dann bin ich spontan etwas ratlos ...
-
Erstens: Für deinen Zweck benötigst du aber genau die "andere" Variante der main() - die mit Parametern
Zweitens: localtime() liefert keinen int, sondern einen struct tm (hatte ich vorhin übersehen). Und egal welches Format du für die Zeitangaben verwenden willst, mußt du dich selber ums' Parsen kümmern (in der C++ FAQ findest du auch einen Beitrag, wie man Zahlenwerte aus einem String herausholen kann).
Drittens: Mit FindFirstFile() und FindNextFile() kannst du dir schrittweise alle Dateien des angegebenen Verzeichnisses geben lassen - in der zurückgegebenen struct steht auch das Datum der Erzeugung und letzten Änderung als FILETIME (und ich bin mir nicht sicher, aber irgendwo sollte es auch eine Umrechnung von tm oder time_t nach FILETIME geben)
(nachsieht - oder du füllst das Wunschdatum in ein SYSTEMTIME und rechnest dann mit SystemTimeToFileTime() um)
-
CStoll schrieb:
Erstens: Für deinen Zweck benötigst du aber genau die "andere" Variante der main() - die mit Parametern
-.- auch das ist jetzt angepasst
wobei ich nicht ganz dahinter steige, warum das so ist. immerhin will ich ja garkeinen wert zurück geben, er soll ja lediglich operationen ausführen.
CStoll schrieb:
Zweitens: localtime() liefert keinen int, sondern einen struct tm (hatte ich vorhin übersehen). Und egal welches Format du für die Zeitangaben verwenden willst, mußt du dich selber ums' Parsen kümmern (in der C++ FAQ findest du auch einen Beitrag, wie man Zahlenwerte aus einem String herausholen kann).
einen struct ... dann muss ich mich also erstmal erkundigen, was ein struct überhaupt ist und wie ich das parsen kann ... das mit dem aus dem string herausholen klingt grad nach mid() und strtoint() (oder wie auch immer die funktionen, falls vorhanden, in c heissen)
CStoll schrieb:
Drittens: Mit FindFirstFile() und FindNextFile() kannst du dir schrittweise alle Dateien des angegebenen Verzeichnisses geben lassen - in der zurückgegebenen struct steht auch das Datum der Erzeugung und letzten Änderung als FILETIME (und ich bin mir nicht sicher, aber irgendwo sollte es auch eine Umrechnung von tm oder time_t nach FILETIME geben)
(nachsieht - oder du füllst das Wunschdatum in ein SYSTEMTIME und rechnest dann mit SystemTimeToFileTime() um)
also vorab: bahnhof ^^
mit findfirst und findnext kann ich noch was anfangen, die begriffe hab ich mir auch schon notiert gehabt. irgendwie übersteigt das grad noch mein verständnis, vielleicht sollte ich das langsam angehen ... zu blöd, dass man soetwas in der schule nicht im ansatz beigebracht bekommt.fällt dir denn eine programmiersprache ein, mit der ich das ganze auf einfachere weise lösen könnte? wichtig ist ja nur, dass das programm halt über die konsole mit parametern aufgerufen werden kann und sich von selbst wieder schließt ....
-
Insanctus schrieb:
CStoll schrieb:
Erstens: Für deinen Zweck benötigst du aber genau die "andere" Variante der main() - die mit Parametern
-.- auch das ist jetzt angepasst
wobei ich nicht ganz dahinter steige, warum das so ist. immerhin will ich ja garkeinen wert zurück geben, er soll ja lediglich operationen ausführen.
Das System/Konsole erwartet einen Fehlerwert als Ergebnis des Aufrufes (auch wenn der meist ignoriert wird), deswegen die int-Rückgabe. Die Parameter benötigst du, um Kommandozeilenparameter (die von der Konsole kommen) in deinem Programm verwenden zu können.
CStoll schrieb:
Zweitens: localtime() liefert keinen int, sondern einen struct tm (hatte ich vorhin übersehen). Und egal welches Format du für die Zeitangaben verwenden willst, mußt du dich selber ums' Parsen kümmern (in der C++ FAQ findest du auch einen Beitrag, wie man Zahlenwerte aus einem String herausholen kann).
einen struct ... dann muss ich mich also erstmal erkundigen, was ein struct überhaupt ist und wie ich das parsen kann ... das mit dem aus dem string herausholen klingt grad nach mid() und strtoint() (oder wie auch immer die funktionen, falls vorhanden, in c heissen)
OK, da fehlen einige Grundlagen - und zuallererst solltest du mal darüber nachdenken, in welchem Format du das Maximalalter angeben willst, der Rest ergibt sich dann meist von selbst (btw, zerlegen kannst du deinen String, indem du \0-Bytes reinquetschst (oder mit man: strtok()), umwandeln in int-Werte mittels atoi() oder strtol()).
CStoll schrieb:
Drittens: Mit FindFirstFile() und FindNextFile() kannst du dir schrittweise alle Dateien des angegebenen Verzeichnisses geben lassen - in der zurückgegebenen struct steht auch das Datum der Erzeugung und letzten Änderung als FILETIME (und ich bin mir nicht sicher, aber irgendwo sollte es auch eine Umrechnung von tm oder time_t nach FILETIME geben)
(nachsieht - oder du füllst das Wunschdatum in ein SYSTEMTIME und rechnest dann mit SystemTimeToFileTime() um)
also vorab: bahnhof ^^
mit findfirst und findnext kann ich noch was anfangen, die begriffe hab ich mir auch schon notiert gehabt. irgendwie übersteigt das grad noch mein verständnis, vielleicht sollte ich das langsam angehen ... zu blöd, dass man soetwas in der schule nicht im ansatz beigebracht bekommt.Bei diesen Funktionen und Klassen hilft eventuell ein Blick in die MSDN weiter.
FindFirstFile() und FindNextFile() durchsuchen einzeln ein Verzeichnis nach Dateien und füllen jeweils eine Hilfsstruktur (WIN32_FIND_DATA) mit Informationen über die gefundene Datei (Attribute, Änderungsdatum, Name, Größe etc) - die Datumsangaben jeweils als FILETIME.
FILETIME ist zwar eine struct, stellt aber letzlich eine 64-Bit Zahl dar (und zählt die Steps (a 100ns) seit 1.1.1601), SYSTEMTIME ist eine Struktur, die das Datum aufdröselt in Jahre, Monate etc.
(Standard C hat analog dazu time_t (Sekunden seit 1.1.1970) und 'struct tm'.fällt dir denn eine programmiersprache ein, mit der ich das ganze auf einfachere weise lösen könnte? wichtig ist ja nur, dass das programm halt über die konsole mit parametern aufgerufen werden kann und sich von selbst wieder schließt ....
Etwas einfacher könnte es mit C++ (und MFC) werden, dort werden einige der nötigen Aufgaben auf Klassen wie CFileFind oder CTime verteilt - um das Parsen/Deuten der Eingabeparameter kommst du trotzdem nicht herum.
-
So, nur um der Sache einen Abschluss zu geben, ich habs jetzt erfolgreich in Delphi gelöst
Trotzdem vielen dank für die Hilfe!