Syntax von Dateiname und -pfad korrigieren



  • Hallo
    Ich versuche gerade einen vorhanden Dateinamen hinsichtlich der Groß-Kleinschreibung zu korrigieren. Aber irgendwie klappt es bisher nicht.

    std::string file = "c:\\wiNDows\\WinDowsUpDAte.log";
    

    soll in

    std::string file = "C:\\Windows\\WindowsUpate.log";
    

    umgewandelt werden. Wie geth man da am besten vor. GetFullPathName und boost::filesystem-Funtkionen brachten bei bisher nicht den erwünschten Erfolg...



  • Du könntest dir die Funktionen aus <ctype.h> anschauen und selber etwas in folgender Art zimmern:

    std::string Capitalize(const std::string &org)
    {
    	std::string s(org);
    	const size_t length = s.size();
    	if(length)
    		s[0]=toupper(s[0]);
    	for(size_t i=1;i<length; ++i)
    	{
    		if(isalpha(s[i]) && (s[i-1]=='\\' || !isalpha(s[i-1])))
    			s[i]=toupper(s[i]);
    		else
    			s[i]=tolower(s[i]);
    	}
    	return(s);
    }
    ...
    std::string file = "c:\\wiNDows\\WinDowsUpDAte.log";
    cout << Capitalize(file) << endl;
    std::string file2 = "c:\\program files\\mEin ordner\\datei.exe";
    cout << Capitalize(file2) << endl;
    

    Ausgabe

    C:\Windows\Windowsupdate.Log
    C:\Program Files\Mein Ordner\Datei.Exe
    

    Falls die Dateiendunng klein geschrieben werden soll, kann die Bedingung zu

    if(isalpha(s[i]) && s[i-1]!='.' && (s[i-1]=='\\' || !isalpha(s[i-1])))
    

    geändert werden.



  • @Falke
    Dafür benutze ich normalerweise boost regex oder boost alogs.

    Was ist eigentlich möchte, ist die real auf der Festplatte vorhandene Syntax!

    also wenn es dort C:\WinDows heißt, dann soll die Hilfsfunktion :\WinDOWS entsprechen umformen

    da muss es doch irgendeine Möglichkeit geben.


  • Mod

    Woher weißt Du bitte was richtig ist? Siehe C:\Windows\SysWOW64 oder C:\Windows\TAPI... Es gibt keine Regel, besonders wenn weil es Acronyme gibt.

    Geht es Dir um existierende Dateien oder möchtst Du eine Regel für neue Dateien haben?



  • es geht ausschließlich um existierende Dateien!

    Die Namen sammel ich aus diversen Eingabedateien mittel RegEx ein. Die dort verwendete Syntax entspricht leider oftmals nicht der im Windows-Explorer angezeigten. Und genau diese benötige ich... Ob es darüber hinaus noch irgendwelche anderen gibt interessiert mich nicht weiter!


  • Mod

    Und warum führst Du nicht einfach FindFirstFile aus um den Namen direkt zu bestimmen?



  • Weil mir FindFirstFile lediglich den korrekten Dateinamen und nicht den korrekten Pfad ermittelt...


  • Mod

    muffmolch schrieb:

    Weil mir FindFirstFile lediglich den korrekten Dateinamen und nicht den korrekten Pfad ermittelt...

    Na und. Dnan machst Du das eben für jeden Teil einzeln in einer Schleife.
    Wenn Du PathRemoveFileSpecimmer wieder aufrufst bekommst Du jeden einzelnen Pfadteil
    http://msdn.microsoft.com/en-us/library/bb773748(VS.85).aspx



  • hmmm... ja, gute Idee. Da ich windowsApi Neuling bin, kannte ich letztgenannte Funktion nicht. Aber damit sollte es dann kein Thema mehr sein!

    Danke!

    und hier die verwendete Lösung. Nicht perfekt, aber solange man nicht Netwerkpfade verwendet und der Laufwerksbuchstabe nicht weiter relevant ist:

    fs::path GetCaseFixedPath( fs::path file )
    {
        file.make_preferred(); // / -> \, da PathRemoveFileSpec nicht mit "/" umgehen kann!!!
    
        WIN32_FIND_DATA FindFileData;
        HANDLE hFind;
    
        char* pFile = new char[ file.string().size()+1 ];
        strcpy( pFile, file.string().c_str() ); //preferred --> / -> \ Anm: PathRemoveFileSpec kann nicht mit "/" umgehen!!!
    
        fs::path retFile;
        assert( retFile.string().find("\\\\")==std::string::npos );  //FindFirstFile hat Probs mit Netzlaufwerken...
    
        do {
            hFind = FindFirstFile(pFile, &FindFileData);
            if (hFind == INVALID_HANDLE_VALUE) 
            {
                if( file.root_path() != fs::path(pFile) )  //Operation fehlgeschlagen
                {
                    delete[] pFile;
                    return file;
                }
                else 
                {
                    retFile =  file.root_path()/retFile;
    		break;
                }
            } 
            else 
            {
                retFile =  fs::path( std::string(FindFileData.cFileName))/retFile;
                FindClose(hFind);
            }
        } while( TRUE==PathRemoveFileSpec(pFile) );	 
    
        delete[] pFile;
        return retFile;
    }
    

Anmelden zum Antworten