2016-12-31 14 views
0

Предполагая, что у меня естьРаспаковка непосредственный родительский каталог из пути к файлу, используя импульс

String t = "c:/foo/foo1/foo2/foo3/file.txt" 

Я хочу, чтобы извлечь "foo3/file.txt".

Как это сделать (с использованием boost или std)?

Вот что я пытался до сих пор:

boost::filesystem::path pathToObject(t); 

Использование pathToObject.filename() я могу извлечь имя файла, конечно. И я играл с t.find_last_of("/"), но мне действительно нужно, как t.find_second_to_last_of("/").

+0

Что вы пробовали? Почему вы не взяли [Tour] (http://stackoverflow.com/tour)? –

+0

Спасибо за ваши ответы и за мой @ joshj777. Вот решение, которое я закончил, используя: std :: string t = pathObject.parent_path(). Filename(). String(); \t \t \t t.добавление ("/"); \t \t \t t.append (pathObject.filename(). String()); –

+0

Вы должны принять один из ответов ниже. (Это может быть ваше собственное, но это не обязательно.) –

ответ

1

Это довольно странно, чтобы извлечь такой путь. Может быть, вы ищете относительный путь? У ускорительной файловой системы есть инструмент для этого. Обязательно дайте documentation хороший обзор. Но чтобы ответить на ваш вопрос:

namespace bfs= boost::filesystem; 
    int main() { 
     bfs::path path("c:/foo/foo1/foo2/foo3/file.txt"); 
     bfs::path target(path); 
     target.remove_filename(); 
     target= target.filename()/path.filename(); 
     std::cout << target << std::endl; 
    } 
+0

Да, в основном я ищу только родительский каталог файла. –

+0

Затем удалите 'filename' и' filename' того, что осталось, это ваш родительский каталог. Это в коде, который я опубликовал. – lakeweb

0

У меня нет компилятора под рукой, чтобы проверить это, но на примере здесь, этот код должен работать в основном или направить в о правильном направлении. Вероятно, это можно было бы упростить даже из того, что я написал здесь.

path p1("c:/foo/foo1/foo2/foo3/file.txt"); 
path p2; 
for (path::iterator it(p1.end()), int i = 0; it != p1.begin() && i < 2; --it, ++i) { 
    path temp = p2; 
    p2 = it; 
    p2 /= temp; 
} 
+0

Это смехотворно сложно. Определенно плохой совет, но у него * есть странная красота. (= –

+0

«Странная красота» объясняется тем, что она значительно более общая, чем большинство других решений. Вероятно, это решение может быть абстрагировано до n уровней пути, а не только с несколькими строками кода. –

+0

Просто зациклируйте на 'n', всегда помня позицию« последней последней косой черты ». Для меня красота заключается в использовании * двух итераторов, где я не думаю, что один из них должен использоваться. –

2

string::find_last_of имеет optional argument, который позволяет определить, как далеко в строку, которую вы ищете.

Таким образом, вы можете определить

size_t second_to_last = t.find_last_of("/", t.find_last_of("/")-1); 
std::string file_with_parent = t.substr(second_to_last+1); 

Второй аргумент говорит ему искать только перед тем последний /.

ВНИМАНИЕ: Это может отличаться от того, что вы хотите, если у вас есть такие вещи, как "C:/bli/bla//blubb.txt". В общем, пути могут быть сложными и запутанными, и попытка покорить их с помощью строковых манипуляций будет работать только для очень хорошо выполненного ввода, который обычно не может быть принят.

Поэтому я рекомендовал использовать надлежащий инструмент для этой работы. * Но поскольку вопрос утверждал, что find_last_of не выполнил бы эту работу, я чувствовал себя вынужденным напомнить людям, что стандартные объекты не так бессильны, как многие, кажется, верят они должны быть.

* Я подозреваю, что путь ускорения lib является одним, но я никогда не работал с ним.

+1

Мне нравится Просто люди просто забывают о стандартных библиотечных утилитах, но лично я бы не пошел сюда, если бы хотел манипулировать трактами, потому что пути не настолько предсказуемы в реальной жизни. +1 тем не менее – sehe

+0

@sehe Whelp, поскольку примечание об этом не работая надежно, видимо, не натолкнулся, я расширил его до смелого предупреждения. С удовольствием сейчас? (= –

+0

О. Я был счастлив раньше. Я тоже не вижу много нисходящих горизонтов, так что вам не нужно так беспокоиться. – sehe

0

Вот решение, которое я закончил с использованием:

std::string t = pathObject.parent_path().filename().string(); 
t.append("/"); 
t.append(pathObject.filename().string()); 

Использование parent_path дал мне только путь. Затем я использовал filename для извлечения только каталога. Затем я добавил filename дочерней директории.

+0

Если бы это был я. Я бы сохранил объекты пути в качестве ускоренных путей. Нет необходимости переходить от строки к пути к строке. Я добавил важную строку в свой ответ. – lakeweb

+0

Хорошая точка. Спасибо! –