2010-11-30 11 views
4

Ok, vor allem möchte ich nicht Boost oder irgendwelche externen Bibliotheken verwenden. Ich möchte nur die C++ Standardbibliothek verwenden. Ich kann meine Strings mit einem bestimmten Begrenzer mit split() Funktion leicht aufgeteilt:C++ - Filename und Dateierweiterung teilen

void split(std::string &string, std::vector<std::string> &tokens, const char &delim) { 
    std::string ea; 
    std::stringstream stream(string); 
    while(getline(stream, ea, delim)) 
     tokens.push_back(ea); 
} 

Ich tue dies auf Dateinamen. Aber es gibt ein Problem. Es gibt Dateien, die Erweiterungen wie haben: tar.gz, tar.bz2, etc. Außerdem gibt es einige Dateinamen, die zusätzliche Punkte haben. Some.file.name.tar.gz. Ich möchte trennen und tar.gzHinweis: Die Anzahl der Punkte in einem Dateinamen ist nicht konstant.

Ich versuchte auch PathFindExtension aber kein Glück. Ist das möglich? Wenn ja, bitte erleuchte mich. Vielen Dank.

Edit: Es tut mir leid, das Betriebssystem nicht anzugeben. Es ist Windows.

+1

Sie wollen nur die C++ Standard Library verwenden, so dass Sie die OS-spezifische Funktion versuchen 'PathFindExtension' ... –

Antwort

6

ich glaube, Sie std::stringfind_last_of bekommen den Index des letzten . nutzen könnten, und substr zu schneiden die Zeichenfolge (obwohl die "komplexen Erweiterungen" mit mehreren Punkten zusätzliche Arbeit erfordern).

+0

Arbeitete perfekt. Vielen Dank. – Ruel

+0

Diese Methode schlägt fehl, wenn Dateien mit Pfaden wie der folgenden gefunden werden: ** C: \ Some.Folder \ somefile ** –

+0

"Ich mache das für Dateinamen" – icecrime

2

Es gibt nichts in der C++ - Standardbibliothek - das heißt, es ist nicht im Standard -, aber jedes Betriebssystem, das ich kenne, bietet diese Funktionalität auf verschiedene Arten.

In Windows können Sie _splitpath() und in Linux verwenden, können Sie verwenden dirname() & Basisnamen()

+0

Sorry, aber' _splitpath() ' hat nicht so gut funktioniert. – Ruel

0

Das Problem ist in der Tat Dateinamen wie *.tar.gz, die nicht einheitlich aufgeteilt werden kann, aufgrund der Tatsache, dass (zumindest in Windows) der .tar Teil nicht Teil der Erweiterung ist. Sie müssen entweder eine Liste für diese speziellen Fälle behalten und einen 1-Punkt string::rfind für den Rest verwenden oder einen vor-implementierten Weg finden. Beachten Sie, dass die .tar.* Erweiterungen nicht unendlich sind und sehr standardisiert sind (es gibt ungefähr zehn davon, denke ich).

+0

Aber das tar-Dienstprogramm verwendet tar.gz, tar.bz2, tar.7z, tar.z usw., soweit ich es sehe.Tar erkennt den Komprimierungsalgorithmus automatisch, wenn Sie eine Datei mit einer solchen Erweiterung erstellen. Ihre Beispiele sind nicht das, worüber ich (und das OP) gesprochen habe (die 'tar. *' Dateien) – rubenvb

+0

GNU tar tut; nicht alle Versionen. Auch keine anderen GNU-Apps oder POSIX-Apps. Das sollte deutlich machen, warum solches Wissen nicht in der C++ Standard Library enthalten sein kann. – MSalters

5

Es gibt keine Möglichkeit zu tun, was Sie wollen, die keine Datenbank von Erweiterungen für Ihren Zweck enthält. Es gibt nichts Magisches an Erweiterungen, sie sind nur Teil eines Dateinamens (wenn Sie gunzip foo.tar.gz erhalten Sie wahrscheinlich ein foo.tar, so für diese Anwendung ist .gz eigentlich "die Erweiterung"). Also, um zu tun, was Sie wollen, erstellen Sie eine Datenbank von Erweiterungen, nach denen Sie suchen möchten, und greifen Sie auf den "letzten Punkt" zurück, wenn Sie keinen finden.

+2

+1 für den Ausdruck "für Ihren Zweck". Das Teilen allgemeiner Namen ist nahezu unmöglich; und nicht sehr nützlich. (Wenn die Anwendung portabel sein muss, sollte die Heuristik "letzter Punkt" erweitert werden, um versteckte Unix-Dateien zu behandeln, deren Namen mit einem Punkt beginnen.) –

0

Sie könnten eine Nachschlagetabelle mit Dateierweiterungen erstellen, von denen Sie glauben, dass sie auftreten könnten. Fügen Sie außerdem eine Befehlszeilenoption hinzu, um der Nachschlagetabelle ein neues hinzuzufügen, wenn Sie auf etwas Neues stoßen. Analysieren Sie dann den Dateinamen, um festzustellen, ob ein Eintrag in der Nachschlagetabelle eine Unterzeichenfolge im Dateinamen ist.

EDIT: Sie können auch auf diese Frage beziehen: C++/STL string: How to mimic regex like function with wildcards?