C++ Kurs

Wenn fertig, bitte Fenster schließen

Lösung zur Lektion "String (Teil 2)"


// Lösung zu String(2)
// Suchen von Zeichen in Strings und zerlegen eines Strings

// Dateien einbinden
#include <iostream>
#include <fstream>
#include <string>

using std::endl;
using std::cout;
using std::string;

// Klasse zum Zerlegen eines vollständigen Pfads in Laufwerk,
// Verzeichnis und Dateiname
class SplitFullPath
{
    string drive;       // Laufwerk
    string path;        // Pfad
    string filename;    // Dateiname
    // Zerlegen des vollständigen Dateinamens (private Member!)
    void SplitIt(const string& fullPath);
public:
    // ctors
    SplitFullPath(const char *pFullPath);
    SplitFullPath(const string& fullPath);
    // Memberfunktionen zum Auslesen der einzelnen Pfad-Elemente
    const string& GetDrive() const;
    const string& GetPath() const;
    const string& GetFilename() const;
};
// Konstruktor
SplitFullPath::SplitFullPath(const char *pFullPath)
{
    SplitIt(string(pFullPath));
}
SplitFullPath::SplitFullPath(const string& fullPath)
{
    SplitIt(fullPath);
}
// Memberfunktion zum Zerlegen des vollständigen Dateinamens
void SplitFullPath::SplitIt(const string& fullPath)
{
    // Übergebenen Pfad duplizieren da er nicht modifiziert werden darf
    string dupString = fullPath;

    // Suche nach :
    string::size_type pos = fullPath.find(':');
    // Falls gefunden
    if (pos != string::npos)
    {
        // Stringanfang bis : in neuen String umkopieren
        drive.assign(fullPath,0,pos+1);
        // Laufwerksangabe aus String entfernen
        dupString.erase(0,pos+1);
    }

    // Suche nach letztem / im String
    pos = dupString.rfind('/');
    // Falls / vorhanden ist
    if (pos != string::npos)
    {
        // Suche nach erstem / im String
        string::size_type startPos = dupString.find('/');
        // Falls mehr als ein / im String vorhanden ist
        if (startPos != pos)
        {
            // Dateinamen ab letztem / im String herauskopieren
            filename.assign(dupString,pos+1,dupString.length());
            // Verzeichnisname ab erstem / bis letztem / herauskopieren
            path.assign(dupString,startPos,pos);
        }
        else
        {
            // Nur ein / im String, dann ist liegt Datei im Root-Verzeichnis
            filename.assign(dupString,1,dupString.length());
            path = '/';
        }
    }
    else
        // kein / im String vorhanden, dann auch kein Verzeichnis
        filename = dupString;
}
// Laufwerk zurückliefern
inline const string& SplitFullPath::GetDrive() const
{
    return drive;
}
// Pfad zurückliefern
inline const string& SplitFullPath::GetPath() const
{
    return path;
}
// Dateiname zurückliefern
inline const string& SplitFullPath::GetFilename() const
{
    return filename;
}

// Die zu zerlegende Dateiangabe
const char* pFILE = "c:/userdata/temp/data.dat";

// main() Funktion
int main()
{
    cout << "Der zu zerlegende Dateiname ist:\n"
         << pFILE << "\n\n";
    // Pfad in Einzelteile zerlegen
    SplitFullPath myPath(pFILE);

    // Laufwerk ausgeben
    string drive = myPath.GetDrive();
    cout << "Laufwerk   : ";
    if (!drive.empty())
        cout << drive << endl;
    else
        cout << "keines\n";

    // Verzeichnis ausgeben
    cout << "Verzeichnis: ";
    string path = myPath.GetPath();
    if (!path.empty())
        cout << path << endl;
    else
        cout << "keines\n";

    // Dateiname ausgeben
    string filename = myPath.GetFilename();
    cout << "Dateiname  : " << filename << endl;

    // akt.Extension geben .bak austauschen
    cout << "Tausche Extension gegen \".bak\"\n";
    // Suche letzten . im Dateinamen
    string::size_type extStart = filename.rfind('.');
    // Falls . gefunden
    if (extStart != string::npos)
    {
        // Alles ab . löschen
        filename.erase(extStart);
        // und nun .bak anhängen
        filename.append(".bak");
        cout << "Neuer Name : " << filename << endl;
    }
    else
        cout << "Keine Extension gefunden!\n";
}