Dateien mit beliebigem Name verschieben



  • Hallo zusammen,

    ich versuche derzeit mir ein Kleines Hilfsprogramm zu schreiben, dass mit txt-Datein in einen Ordner verschiebt, sobald ihr Inhalt bestimmte Merkmale aufweist. Dabei ist anzumerken, dass mit die Dateinamen unbekannt sind.

    Das Öffnen sowie das Auslesen und Erkennen der Merkmale habe ich bereits geschafft. Jetzt möchte ich diese Datei (wahrscheinlich mit MoveFile) in einen Unterordner Verschieben.

    Es funktioniert, wenn ich den Dateinamen direkt angebe:

    char Test[60] = "Datei1.txt";
    MoveFile(Test, "C:\\Users\\Pfad\\Datei1.txt"); 
    

    Ich möchte aber, dass ich anstatt dem char "Test" meinen jeweiligen Dateinamen angeben. Diese habe ich folgendermaßen ermittelt.

    WIN32_FIND_DATA data;
    HANDLE hFind;
    LPCTSTR FileName="C:\\Users\\Pfad\\*.txt" ;
    bool ret;
     
        hFind = FindFirstFile( FileName ,  &data);
        
        do
        {	
         
        cout<<'\n'<<'\n'<<data.cFileName<<endl;
    
    }
     
     
                while ( FindNextFile( hFind, &data) != 0  );
                FindClose(hFind);
     
    
    

    Wenn ich z.B. data.cFileName anstatt meiner hier fixen variable Test eingebe, wird die Datei leider nicht verschoben. Kann mir wer helfen?

    Danke und viele Grüße

    Flo



  • Warum zeigst du nicht den Code, der nicht funktioniert?



  • @enwa sagte in Dateien mit beliebigem Name verschieben:

    Kann mir wer helfen?

    Was sagt GetLastError()?

    Bitte nach WinAPI verschieben. Danke.

    //edit: Bist Du sicher, daß "C:\Users\Pfad\" (der Pfad, in dem Du nach "passenden" *.txt-files suchst) auch das aktuelle Arbeitsverzeichnis deines Programmes ist? Wenn nicht musst Du MoveFile() den absoluten Pfad zur zu verschiebenden Datei geben.


  • Gesperrt

    @enwa sagte in Dateien mit beliebigem Name verschieben:

    Es funktioniert, wenn ich den Dateinamen direkt angebe:

    char Test[60] = "Datei1.txt";
    MoveFile(Test, "C:\\Users\\Pfad\\Datei1.txt");
    

    wieso nicht

    std::string filename = "Datei1.txt";
    std::string path = "C:\\Users\\Pfad\\";
    std::string moveto = filename + path;
    MoveFile(filename.cstring(), moveto.cstring());
    

    oder so ähnlich, dann sollte es möglich sein verschiedene Pfade und Dateinamen zu kombinieren.



  • @titan99_ sagte in Dateien mit beliebigem Name verschieben:

    oder so ähnlich

    Wennn Du Dir nicht sicher bist, dann probier es aus, bevor Du eine falsche Antwort gibst. So in dieser Form ist das nicht hilfreich.


  • Gesperrt

    @swordfish sagte in Dateien mit beliebigem Name verschieben:

    Wennn Du Dir nicht sicher bist, dann probier es aus, bevor Du eine falsche Antwort gibst. So in dieser Form ist das nicht hilfreich.

    #include <iostream>
    
    int main()
    {
        std::string filename = "Datei1.txt";
        std::string path = "C:\\Users\\Pfad\\";
        std::string moveto = path + filename;
        
        std::cout << moveto.c_str() << std::endl;
    }
    

    Sorry, stimmt. Habe es jetzt geändert und ausprobiert https://www.onlinegdb.com/online_c_compiler#😳

    Edit:



  • @titan99_ sagte in Dateien mit beliebigem Name verschieben:

    // ...
    

    Sorry, stimmt. Habe es jetzt geändert und ausprobiert

    Super Beispiel wo der Aufruf von string::c_str() völlig sinnfrei ist. (das std::endl übrigens auch). #include <string> fehlt. Lass das!

    @titan99_ sagte in Dateien mit beliebigem Name verschieben:

    https://www.onlinegdb.com/online_c_compiler#😳

    Ja ne, ist klar.


  • Gesperrt

    @swordfish sagte in Dateien mit beliebigem Name verschieben:

    Sorry, stimmt. Habe es jetzt geändert und ausprobiert
    Super Beispiel wo der aufruf von string::c_str() völlig sinnfrei ist. (das std::endl übrigens auch). #include <string> fehlt. Lass das!

    Also der Aufruf von string::c_str() sollte dazu da sein, weil MoveFile einen LPCTSTR fordert. std::endl weil ich nicht ganz sicher bin, ob der Online-Compiler einen solchen fordert, aber es stimmt, ich kenne den Unterschied zwischen '\n' und std::endl nicht. Dachte in std::endl hat es noch flush oder so etwas. Wirklich stören tut es glaube ich nicht. <string> ist doch in <iostream> enthalten wenn ich mich nicht täusche. Vom Stil her kann ich verstehen, das man <string> trotzdem nochmals "einbindet"(?).

    Gut und zusätzlich wird noch durch '\\' im std::string "anders" als bei char[], oder nicht?

    @swordfish sagte in Dateien mit beliebigem Name verschieben:

    @titan99_ sagte in Dateien mit beliebigem Name verschieben:

    https://www.onlinegdb.com/online_c_compiler#

    Ja ne, ist klar.

    Verstehe ich nicht ganz, ist etwas mit online compilern nicht gut?



  • @titan99_ sagte in Dateien mit beliebigem Name verschieben:

    <string> ist doch in <iostream> enthalten wenn ich mich nicht täusche.

    Nein ist nicht der Fall. Wozu auch.

    @titan99_ sagte in Dateien mit beliebigem Name verschieben:

    Gut und zusätzlich wird noch durch '\\' im std::string "anders" als bei char[].

    Bahnhof.

    Komm. Lass es. Das führt den Thread nur weiter sinnlos off Topic. @enwa soll erstmal die an ihn gestellten Fragen beantworten.



  • Ok, alsoschonmal danke für euren Input. Das ist mein erster Betrag hier und ich hätte nicht gedacht, dass überhaupt jemand antwortet. Also schonmal vielen Dank!

    Also das Programm liegt im Ordner wo auch die Datein liegen, daher ist die Fehlerquelle schonmal ausgeschlossen. Wie gesagt, wenn ich den Dateinamen manuell eingebe, funktioniert es, im Betrieb des ganzen wird es aber nicht so sein, dass ich die Dateinamen kenne.
    Ich habe ich nicht das Problem, Datein mit mir unbekanntem Namen zu öffnen oder gar deren Inhalt auszuwerten.
    Mein einziges Problem ist es derzeit noch, dass ich die vorhandene Datei anschließend in einen Unterordner verschieben möchte. Das funktioniert noch nicht so recht. Ich bekomme keine Fehlermeldung. Er verschiebt es einfach nicht.

    Ich werde es später auf jeden Fall noch einmal mit absoluten Pfaden versuchen. Vielleicht tut es auch ein Workaround. z.B. Das ich den Inhalt der entsprechenden Datei kopiere und im anderen Verzeichnis neu anlege. Dann muss ich den Ordner selbst nur regelmäßig löschen.



  • @enwa sagte in Dateien mit beliebigem Name verschieben:

    Also das Programm liegt im Ordner wo auch die Datein liegen, daher ist die Fehlerquelle schonmal ausgeschlossen.

    Das bedeutet nicht automatisch, daß das auch das Arbeitsverzeichnis des Programms ist!!

    @enwa sagte in Dateien mit beliebigem Name verschieben:

    Ich bekomme keine Fehlermeldung. Er verschiebt es einfach nicht.

    Wenn MoveFile() fehlschläft, die Datei also nicht verschieben kann, gibt die Funktion 0 zurück. Dann ist es an Dir, GetLastError() aufzurufen, um mehr über den jeweiligen Fehler zu erfahren. Also: Was liefert GetLastError()? Wie @manni66 schon forderte: Zeig den betreffenden Code, am besten ein aufs Wesentliche reduziertes, kompilierbares Beispiel.



  • Und weil's gerade ein bisschen dazupasst: Das Korrekte Muster um GetLastError aufzurufen ist:

    BOOL const success = SomeWinAPIFunction();
    DWORD const error = GetLastError(); // unmittelbar nach dem WinAPI Aufruf
    if (!success)
    {
        // Fehlermeldung ausgeben
    }
    

    Bzw. was auch noch geht:

    BOOL const success = SomeWinAPIFunction();
    if (!success) // unmittelbar nach dem WinAPI Aufruf
    {
        DWORD const error = GetLastError(); // als erste Anweisung innerhalb des if Blocks
        // Fehlermeldung ausgeben
    }
    

    Sobald du nämlich anfängst sowas zu schreiben:

    BOOL const success = SomeWinAPIFunction();
    if (!success)
    {
        std::cout << "Error: could not open file '" << fileName << "', error code " << GetLastError() << "\n";
    }
    

    ...läufst du Gefahr dass Code der vor GetLastError() ausgeführt wird, auch wenn er harmlos aussieht, den gespeicherten "last error" Code ändern könnte. Was dann u.A. zu Fehlermeldungen wie "Error XYZ: The operation completed successfully" führen kann.

    Das selbe gilt natürlich auch für andere Systeme mit Fehlernummern die man sich nach einem fehlgeschlagenen Aufruf irgendwie abholen kann, z.B. auch die ganze POSIX errno Katastrophe.



  • Hallo, sorry, dass ich nicht mehr geantwortet habe... aber Hura Hura,
    Ich konnte mein Problem lösen 🙂

    Fragt mir nicht, was ich groß anders gemacht habe. Ich habe meinen Code lediglich sequenziell hinterienander aufgeschrieben, das heißt erst Datein listen lassen (vollständig) dann verschieben.

    WIN32_FIND_DATA data;
    HANDLE hFind;
    LPCTSTR FileName="Pfad\\*.txt" ;
    bool ret;
     
    hFind = FindFirstFile( FileName ,  &data);
     
     
     		
        
        do
        {	
         
         	FILE *A;
      		A = fopen ("1a.txt", "w");                                                                                    
    		fclose (A); 
         
        cout<<'\n'<<'\n'<<data.cFileName<<endl;
      
        	FILE *Dat;
      		Dat = fopen ("lesen.txt", "w");                                               
       		fprintf (Dat, data.cFileName);      
    		cout << data.cFileName << '\n' ;                                        
    		fclose (Dat); 
    		
    	if (p_BK2 == 1)
    	{
    						                 	
            ifstream file("lesen.txt");
    		file.getline(uhc, ' ');    
    		MoveFile(uhc, "Pfad\\ordner1\\Datei_ver.txt");
      }
      
      else
      {
      	p_BK1 =0;
      }
      
      	if (p_BK2 == 1)
    	{
    						                 	
            ifstream file("lesen.txt");
    		file.getline(uhc, ' ');    
    		MoveFile(uhc, "Pfad\\ordner2\\Datei_ver.txt");
      }
      
      else
      {
      	p_BK1 =0;
      }
      	
         ifstream datei(data.cFileName);
    
    // Null setzen der Prüfidentifikatoren
       
        
        
                        for (k = 0; k <= 100; k++)
                            {
                                    getline(datei, zeile);
    
    										   
    									 	if (zeile == BK3)
                                       		{
                                      		p_BK2 = 1;
                                      
                                       		}
    
                                       		else if (zeile == BK2)
                                       		{
                                        	p_BK3 = 1;   
    									
    									//	MoveFile(("%c", uhc), "Pfad\\Datei1.txt");
    										          	                        
                                       		}				
                         	}
                         	
          
         
               /*------------- Datei schließen --------------------------------------------- */
                            datei.close();
                            
                            
                       
     
    }
     
     
                while ( FindNextFile( hFind, &data) != 0  );
                FindClose(hFind);
     
     
        
        
            
     
                return 0;
    }
    
    

    Is alles noch ein bisschen unsauber, aber ich räume noch auf bzw. habe das im richtigen Programm schon getan.



  • Yes, no ... is clear! 😔


Anmelden zum Antworten