1. "reales" Projekt. Kopieren, bzw. verschieben



  • Achtung : Das wird etwas länger.

    So heute ist mir beim kopieren einiger Dateien am PC die Idee für mein 1. "reales" Projekt gekommen, für das ich noch einiges an Infos und / oder Tipps brauchen könnte.
    Wie evtl. aus meinen anderen Beiträgen bekannt, lerne ich C ursprünglich "nur" Hobby , bzw. Interessemäßig, beruflich haben sich Hochsprachen nicht sooo stark in der Automatisierungsbranche durchgesetzt.

    So, auf zum wesentlichen.
    Ich habe auf einer Externen Festplatte "Dj-Sets" im mp3 Format gespeichert. Durch die Jahre sind das ziemlich viele geworden, somit eine vielzahl an Ordnern der jeweiligen Interpreten.
    Da ich (leider) ziemlich faul bin, landen die downgeloadedten Sets erst mal auf der PC Platte und werden dann von mir "manuell" 2-3 mal im Jahr auf die Externe kopiert, bzw. ausgeschnitten.
    Das ist ziemlich nervtötend, da da schonmal 100- 150 mp3 (größe à 95 - 125 MB) zusammenkommen.

    Also, der C-Beginner will jetzt ein Programm schreiben, das die kopiererei für mich erledigt. Tolle Idee, jedoch schon beim zurechtlegen des "Grundablaufs" bin ich jetzt doch etwas unsicher, da ich nicht will das das Programm zwar funktioniert aber im Endeffekt "totalter Käse" ist. Sowas sehe ich beruflich oft genug.

    Also ich habe mir das so gedacht :

    Ich erstelle erstmal eine Art "Referenzliste" in der mal steht welche "Interpretenordner" es auf der Externen gibt.

    1.)Hinderniß : dann müsste ich aus meinem Ordner auf der PC-Platte die Dateinamen der ganzen mp3´s einlesen. Tja, aber wie? Ich habe absolut 0-Plan von der WinApi also weiß ich auch nicht wirklich nach welchen Befehle ich suche... und ob das überhaupt so geht? (=> ein Pendant zu "Ausschneiden" wäre am besten, weil das irgendwie schneller geht als kopieren)

    sollte das geklappt haben :

    Der "Name" meiner Dateien ist immer gleich : Interpret - Live @ bla bla bla.mp3

    Jetzt würde ich einfach mal prüfen ob der Teil-String bis zum "-"-Zeichen des unter 1) "ausgelesenen" Dateinamens in meiner Referenzliste steht.

    Wenn ja : Toll, kopieren => evtl. 2. Hinderniss : mit meinem derzeitigen Wissenstand würde kopieren über String basteln und an system(kopier_string) schicken. Abhilfe ?? Winapi befehl ???

    Wenn nein : Tja, dann gibt´s so ne Art Buffer - Ordern . (Später,wenn das mal läuft, will ich den buffer-ordner untersuchen ob evtl. der Interpret schon 3x vorhanden ist und ihm dann nen "eigenen" Ordner spendieren).

    Das kopieren, bzw. prüfen soll dann in ner Schleife laufen bis keine "dateinamen" mehr ausgelesen werden können oder meintetwegen mir ner "Sperr-mp3" àla do ... while ( auslesen != z_end.mp3).

    Wie genau das ganze dann programmiert wird stellt sich dann noch raus.

    Also ich bräuchte jetzt nen "kleinen" tritt in richtung passende Befehle und ne einschätzung ob das ganze so laufen kann oder ob die "Grundidee" schon zum scheitern verurteilt ist, bzw. auf was ich noch achten sollte.

    Danke schonmal an alle die bis hier gelesen haben.

    Noch nen schönen Sam-Abend!!!

    beginner

    Ps.: OFF-Topic : eigentlich ist es mein 2. Projekt das nicht nur experimente beinhaltet. Hab vor kurzen ein von mir vergessenes .rar Archiv passwort ge"brutforced"... naja, ich wusste noch die beiden Buchstaben , also musste ich nur noch Zahlenkombinationen zusammenfügen und mit (ich weiß es ist nicht schön....) System(code) rausschicken. Stolz wie Harry Hirsch, auch wenns billig ist. *grins*



  • So 100% verstanden habe ich nicht was du genau vorhast. Also, schon dass du Dateien von Ort A nach Ort B verschieben willst, aber nach welchem Schema ist mir noch nicht ganz klar.

    Mach es Schritt für Schritt. Also schreib erst einmal ein Programm was überhaupt eine Datei von einem Ort zu einem anderen verschiebt. Das kannst du über OS-Spezifische Funktionen machen per API, aber auch per exec Befehle an eine Konsole im Hintergrund schicken. Dort müsstet du dann "nur" die richtigen Zeichenketten zusammen stellen wie "mv ort1\bla1.mp3 \ort2". Oder du nutzt Libs wie Qt.

    Wie die einzelnen Funktionen in der API oder den Frameworks oder auf der Konsole heißen kannst du dir sicher schnell ergoogeln. Ich weiß die auch nicht aus dem Kopf, zumal ich auch nur ein Hobbyprogrammieren unter OSX bin und von Windows überhaupt keine Ahnung habe.



  • Mach es Schritt für Schritt. Also schreib erst einmal ein Programm was überhaupt eine Datei von einem Ort zu einem anderen verschiebt. Das kannst du über OS-Spezifische Funktionen machen per API, aber auch per exec Befehle an eine Konsole im Hintergrund schicken. Dort müsstet du dann "nur" die richtigen Zeichenketten zusammen stellen wie "mv ort1\bla1.mp3 \ort2".

    So "leicht" ist das nicht. Ich find mich mit der Api nicht zurecht.
    Und ->mv ort1\bla1.mp3 \ort2"<- bringt mir nichts, da ich ja bla1.mp3 nicht kenne und ort2 auch nicht, bzw. das immer wechselt also irgendwann dann Zeiger sind die mir die bis jetzt mir unbekannt "->lies mal alle Dateinamen im aktuellen Ordner ein<-" funktion bringt, bringen sollte, ....

    Mir fällt jetzt auch nicht wirklich ein wie ich mit "Standart-C" funktionen den "Quellordner" auslesen kann. Mal sehn, vielleicht fällt dem ein oder anderen noch was ein.



  • Aber du muss doch eh ein großes Programm(ganzen Programm) in kleinere Teilprobleme zerlegen, bis sie für dich lösbar sind und wenn sie dies nicht sind, dann musst du dir das Wissen für diesen kleine Teillösung aneignen, da gibt es keinen Shortcut für.

    Ein Teilproblem ist es überhaupt eine Datei von A nach B zu bringen, egal woher die Dateinamen kommen, denn dies ist wieder ein ganz anderes Problem was isoliert behandelt werden kann. Womit du natürlich anfängst ist dir überlassen.

    Wenn du mit der WinAPI arbeiten willst dann fange mit einen Grundgerüst an und mache dich ein wenig damit vertraut und dann hast du auch das Wissen um dir die passenden API-Funktionen raus zu suchen und vor allem selbstständig testen zu können.

    Wenn du C nicht kannst, lernen es.
    Wenn die du WinAPI nicht kennst, mache dich damit vertraut.
    Wenn du Probleme mit Datenstrukturen und Algorithmen hast dann schau sie dir, es gibt da mehr als genug.
    Aber vor allem versuche deine Probleme zu formalisieren, aufzuteilen und aufzuschreiben, dann kannst du Schritt für Schritt vorgehen.
    Bei konkreten Fragen ist ein Forum dann das richtige.
    Aber vor allem, übernimm dich nicht, das endet ganz schnell in Frust. Ich weiß dass kleine Programme wie "Ich lesen eine Textdatei ein und vertausche jeden 3.Buchstaben und löschen jeden 4. und schreibe die Datei dann wieder auf Platte" etc. Aber sie zeigen dir wo du noch Lücken hast.



  • Ich persönlich finde C für diese Art von Software extrem ungeeignet.

    Willst du dafür nicht einfach die Skriptmöglichkeiten einer Shell verwenden. Zum Beispiel die Powershell unter Windows, oder die Bash unter Linux?



  • Mit Standard-C geht sowas nicht, aber in der Fragestellung wird ja von der WinApi gesprochen.
    Es wäre also sinnvoll gewesen, wenn Du die Frage im WinAPI-Forum gestellt hättest ...

    Erste Teilaufgabe: Dateien suchen geht mit FindFirstFile() sowie FindNextFile()

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa365200.aspx



  • ...



  • Hmmm...
    Also Danke ersmal an alle antwortenden.
    => FindFirstFile() sowie FindNextFile() <= werd ich mir noch genauer ansehen und mal ein paar "Experimente" starten. Finde die MSDN Hompage extem unübersichtlich , aber egal.

    Es wäre also sinnvoll gewesen, wenn Du die Frage im WinAPI-Forum gestellt hättest ...

    Hatte ich mir bereits überlegt. Habe aber absichtlich im C Forum gepostet, da das ganze ja auch in C geschrieben werden sollte und die minimale Chance auf eine Antwort wie : "Hey... Benutz statt der Api lieber die HexHex-Zauberfunktion XYZ!! " bestand ja doch.

    Ich persönlich finde C für diese Art von Software extrem ungeeignet.

    Willst du dafür nicht einfach die Skriptmöglichkeiten einer Shell verwenden. Zum Beispiel die Powershell unter Windows

    Tja, den Eindruck habe ich mittlerweile auch, hab mir das etwas easier vorgestellt.
    Danke für den Tipp mit Powershell, werde mir das zu gegebener Zeit mal genauer ansehen.

    Fuck , das ganze depremiert mal wieder, ich verdiene zwar mein Geld mit Programmieren, aber ne Datei auf meinem Homerechner hin und herschieben ist schon wieder ein Hexenwerk. Fuck it.



  • Das hin- und herschieben von Dateien ist (auch mit C) kein Problem.

    Schwieriger ist es heraus zu finden, welche Dateien das sind.
    Du kannst eine Textdatei schreiben, in dem alle Dateien drin stehen.

    Das sollte für den Benutzer einfach sein, damit es kein "totalter Käse" wird.

    Dazu brauchst du Directory-Funktionen, Sringverarbeitung und evtl. nach eine GUI.

    Und dafür gibt es bessere Sprachen als C (war mein erster Gedanke als ich das gelesen habe)

    Das kopieren ist dann ein kleiner Rest.



  • Ja, das ist wohl war, hab mir das "simpler" vorgestellt.
    C ist wohl wirklich nicht die zu bevorzugende Sprache für sowas.

    Informatikers Tipp mit Powershell hat mich ein gutes Stück weitergebracht.

    Ich werde wohl einige Funktionen "auslagern", Ordnerdurchsuchen , filtern und Ergebnis in eine .txt Datei schreiben ist mit Powershell ein Klacks.



  • Warum auslagern?
    Auch das kopieren/verschieben wird damit einfacher sein.

    Der nächste Schritt wäre dann eine Scriptsprache wie Pearl, Ruby, Tcl. Mit Tk kannst du da auch eine GUI machen.



  • Da gebe ich dir schon recht.
    Für das "schöne" Programm werde ich mich noch mit Skripting usw. befassen und dann mal versuchen das ganze "elegant" zu lösen.

    Aber da ich ja auch ein Sturkopf bin, bastle ich natürlich weiter an einer C-Umsetzung rum 🙂 Habe mit aber damit abgefunden das dies in Richtung "Käse" führt. Aber mein "String-Handling" gehört eh verbessert.

    Generell noch ne Frage... Würde sich c++ oder c# eher für soetwas eignen?



  • beginner_logout schrieb:

    Generell noch ne Frage... Würde sich c++ oder c# eher für soetwas eignen?

    Die Sprache ist hier zunächst weniger entscheidend als die verwendetet Bibliothek.

    Falls du in C++ oder C# direkt die Winapi verwendest, dann nimmt es sich nicht viel im Vergleich zu C.

    Allerdings bieten diese beiden Sprachen schon deutlich mehr Möglichkeiten eine elegante Bibliothek zu implementieren, welche es dir auf recht bequeme Art und Weise erlaubt Dateien zu kopieren/verschieben.

    Für C gibt es aber sicher auch elegantere Bibliotheken. Das Hauptproblem sehe ich bei C aber immer in der Fehlerbehandlung.

    Wer diese korrekt durchführt, der hat sehr verbosen Code. Da jeder Rückgabecode ausgewertet werden muss und entsprechend reagiert werden muss.



  • Aha.
    Naja, so weitreichend ist mein Wissenstand noch nicht. Habe bis jetzt nur mit der Standard Bibliothek gearbeitet.

    Die Win Api ist für mich auch noch ein Buch mit 7 Sigeln , aber da werd ich mich demnächst noch versuchen etwas einzuarbeiten.

    Muss gestehen, ich habe meistens für meine "mini & Experimentier" Programm die System() -Schnittstelle benutzt. Unschön, aber mangels weiterer Kenntnisse ganz praktisch.

    Das Hauptproblem sehe ich bei C aber immer in der Fehlerbehandlung.

    Ja, ja die Fehlerbehandlung. Ich hasse sie beruflich schon 🙂
    Unterscheide mal ob es Fehler der Klasse "Kann der Bediener selbst beheben", "Ein Elektriker wird benötigt", "Ein Programmierer wird benötigt" und "Holen Sie einen Schrottkontainer" :-))



  • Na soviel Fehlerbehandlung sollte ein Programm nicht haben. Das ist halt wichtig bei Sachen die von Außen kommen wie Dateien, Eingaben. Aber die ganze interne Maschenerie sollte keine weitere Fehlerbehandlung mehr brauchen. So mache ich dies auch in C. Dateien und Eingaben werden ausführlich geprüft ansonsten natürlich Pointer auf Null getestet, aber ansonsten ist da weiter nix aufregendes bei mir an Fehlerbehandlung drinne. Ich brauche da nicht zisch Ebenen nach oben reichen oder dergleichen.

    Man den ganzen Softwaredesignprozess auch extrem verkomplizieren und das machen ganz viele Entwickler heute auch. Was die alles an überflüssigen Code für einfach Aufgaben fabrizieren ist unglaublich.



  • Kurze Rückmeldung.... Bin fast fertig mit dem Programm, erste "Testversuche" liefen ganz gut.
    Ist echt bescheiden mit C umzusetzen.... Aber es funktioniert für meine bescheidnenen Bedürfnisse soweit.

    Schön... ist es nicht geworden. Powershell Skrpte die über System() angesprochen werden... Enormer Aufwand beim String-Handling.... und bis jetzt absolut unflexibel. Da sich die Ordner nicht ändern werden, muss es jetzt auch nicht sooo flexibel sein.

    Kurz und knapp : Die "erweiterte" Version wird nicht mehr in C sein, soweit tut es aber was es soll und war ne gute Übung.

    Poste demnächst den Horror Code, evtl. mag der ein oder andere drübersehen.



  • beginner88888 schrieb:

    Powershell Skrpte die über System() angesprochen werden...

    Das ist aber völliger Quatsch.



  • Quatsch in Vollendung, das kann ich nicht abstreiten.

    =>Die Skripte werden erst im Programm generiert und dann über System() angesprochen 👎 👎



  • Nachtrag:
    Programm ist mittlerweile 3 mal im "Einsatz" gelaufen.
    Eine tolle Sache. Jetzt nicht unbedingt wie es programmiert ist, das hatten wir ja schon.
    Aber mich freut es ja tierisch, das ich es wenigstens(Wenn auch mit bescheidenen Mitteln) hinbekommen habe, mir die Sortierarbeit nicht mehr machen zu müssen. Jiha 🙂

    Falls es jmd. interessieren sollte(glaub zwar nicht, aber vielleicht sieht ja jmd. noch was zu "verbessern" in diesem wohl Negativ-Beispiel), hier mal ein bisschen Code.

    Ps.: Habe jetzt insgesamt 420 Mp3´s automatisch sortieren lassen. Wie geil :-))

    Hier "lagere" ich mal in Powershell aus, erstelle die Skripts usw

    #include <stdio.h>
    #include <stdlib.h>
    
    int init(void){
    
    int dummy, dir_anzahl;     
    
    char *command={"Get-ChildItem -Filter *.mp3 -Name | Out-File  musik.txt"} ;//{"Get-ChildItem -Filter *.mp3 -Name D:\\_ext | Out-File D:\\_ext\\musik.txt"};
    char *sys_cmd={"powershell %CD%\\c1"};
    char *command2={"dir -Exclude *.* -Name   O:\\Musik\\0_SETS_0  | sort-object name| Out-File referenz.txt "};  
    char *dir_cmd={"powershell %CD%\\c2"};
    FILE *shell_dat, *dir_dat;
    FILE *dump;
    FILE *connect;
    
    //check connection to EXT
    
    if ( (connect=fopen("O:\\connect.itf", "w")) == NULL){
         puts("Error...EXT-HDD Not CONNECTED!!!!");
         system("pause");
          exit(0);
       }
       else{
             fclose(connect);
             puts("HDD Connected, del itf-file");
                       if ( (remove("O:\\connect.itf")) != 0 ){
                            puts("Error deleting Connection File!!");
                            system("Pause");
                            exit(0);
                         }
            }
    
    if (  (dump=fopen("0000.mp3", "w")) == NULL){
          puts("Error Creating Dump MP3!!!");
          system("pause");
          exit(0);
       }
    puts("Dump Created!!!\n");
    fclose(dump);
    
     // Read in the MP3 Directory => Create Skript
    if ( (shell_dat=fopen("c1.ps1", "w")) == NULL){         //in current directory!!!
         puts("Error Creating Reading Script File");
         system("Pause"),
         exit(0);
         }
    fprintf( shell_dat, command);
    fclose(shell_dat);
     //  run the 1st script  
    if  ( (dummy=system(sys_cmd)) !=0){
          puts("Error with the 1st Script!!!");
          system("Pause");
          exit(0);
          }
    puts("MP3's Sucsessfully READ IN!!!\n");      
     // Create the 2nd script
    if ( (dir_dat=fopen("c2.ps1", "w")) == NULL){    //in current directory!!!
         puts("Error Creating 2nd Skript!!!");
         system("Pause");
         exit(0);
         }
    fprintf(dir_dat, command2);
    fclose(dir_dat);   
    
    // run the 2nd script
    dummy=0;
    
    if ( (dummy=system(dir_cmd)) != 0 ){
         puts("Error with teh 2nd Script!!!!");
         system("Pause");
         exit(0);
         }   
    puts("Directory Sucsesfully READ IN!!!\n"); 
    // Everything is fine, del the Scripts
    remove("c1.ps1"); 
    remove("c2.ps1");
    remove("0000.mp3");
    puts("Scripts & Dump  Cleaned!!");
    puts("now... Cleaing the Ref File of Dirs....\n");
    dir_anzahl=clean_ref();          // Read the Directorys from the EXT-HDD  !!!!!
    if (dir_anzahl==0){
         puts("Error on Cleaning the DIRS!!!!");
         system("Pause");
         exit(0);
       }
    puts("\n....done\n");
    remove("referenz.txt");  
    puts("\n.......refernz.txt  deleted......\n"); 
    return dir_anzahl; 
    }
    

    Hier wird gesucht und dann kopiert...

    #include <stdio.h>
    #include <stdlib.h>
    #include "sys.h"
    #define max 75
    
    void search (MP3 *fptr, int ri_fil, int dir_anzahl){
    
    FILE *dptr;
    char buffer[max];
    int i,j, copy_ct=0;
    MP3 *sptr;
    
    if ( (dptr=fopen("dirs.cl", "r")) == NULL ){
         puts("Error on opening dirs.cl");
         exit(0);   
         }
    
    printf("%d - Files must be searched\n", ri_fil);
    system("color 2");      
    
     for(i=2; i<dir_anzahl; i++){
        fread(buffer, sizeof(DIRS), 1, dptr); 
        puts("\n");
        puts(":::::::::::::::::::::::::::::::::::::");    
        puts(buffer);
        puts("=>will be searched now");
        puts("::::::::::::::::::::::::::::::::::::::");
    
        sptr=fptr;    //the Search Pointer  
            for(j=0; j<ri_fil; j++){
                     puts(buffer);
                     puts(sptr->id);
                       if ( strcmp(buffer, sptr->id) == 0){
                             puts("Matching Item Found!!!");
                             puts("try to copy....");
                             ccmd(sptr);    
                             copy_ct++;
    
                        }
                     sptr++;
              }
    
       }
    
    printf("%d Files  kopiert!!!\n", copy_ct);
    system("pause");    
    fclose(dptr);     
    
    }
    

    Die "fiffelige" Arbeit war aber die Strings "passend" zu bekommen.

    Hier die MP3 Dateinamen aus dem Powershell Skript:

    #include <stdio.h>
    #include <stdlib.h>
    #include "sys.h"
    #define max 150
    #define _MAXMP3 150
    
    void clean(int dir_anzahl){
    //Var
    FILE *szg, *ref;
    int i, j, k, trenn, t_copy, dummy;
    size_t len1, read_in=0;
    char sbuffer[max], dbuffer[max-50], idbuffer[max-75], *read, *show;
    MP3 log [_MAXMP3], *sptr , *hsptr  ;
    //End_Var    
    
    if ( (szg=fopen("musik.txt", "r")) == NULL){
         puts("Error Opening Source File");
         system("pause");
         exit(0);
     }
    sptr=log;
    
     fgets(sbuffer, max, szg);    //read the first Entry. It is DUMP!!! 4get it
    
    do { 
         read=fgets(sbuffer, max, szg);    // Here the "Real" reading starts
    
          j=0;
          for(i=1; i<max; i+=2){       // Clean the Garbige Bytes between the Letters
            dbuffer[j]=sbuffer[i];          
            j++;
          }  
    
            for (k=0; k<max; k++){        // search the .mp3 chars
                if ( dbuffer[k]=='.' && dbuffer[k+1]=='m' && dbuffer[k+2]=='p'){
                   dbuffer[k+4]='\0';   //Terminate the String
                 }
             }
              strcpy(sptr->filename, dbuffer);  // Filename now in struct
              len1=strlen(sptr->filename);
    
               for (trenn=0; trenn < len1; trenn++){  //Get the ID(interpret) of the File
                  if ( dbuffer[trenn] == '-' ){
                      for (t_copy=0; t_copy < (trenn-1); t_copy++){
                          idbuffer[t_copy]=dbuffer[t_copy];
                           idbuffer[t_copy+1]='\0';
                       }
                   }
                 } 
               strcpy(sptr->id, idbuffer); 
               sptr++;
               read_in++;   
    
    } while (read!=NULL);  
    read_in-=2;  // one is the dump, one is the 0 of the array  . ... is ok so
    printf("%d  Files eingelesen\n", read_in);            
    fclose(szg);   
    
    search(log,  read_in, dir_anzahl);      //now compare the Directorys with the Buffer-ID-s
    

    Wer bis jetzt noch nicht gekot... hat, möge es jetzt tun, ich find´s trotzdem irgendwie toll ;-))

    OT:

    Allerdings bieten diese beiden Sprachen schon deutlich mehr Möglichkeiten eine elegante Bibliothek zu implementieren, welche es dir auf recht bequeme Art und Weise erlaubt Dateien zu kopieren/verschieben.

    Ich muss mich jetzt dann beruflich mal ein bisschen mit C# beschäftigen... (Scheinbar kann man bei Siemens jetzt mit C# ein bisschen "Skripten"...)...
    Welche Bibliotheken aus dem Zitat wären da evtl. für Dateiarbeit erwähnenswert?


Anmelden zum Antworten