-7

I have a full path like /a/b/c/text.txt

How to get /a/b/c and text.txt using c++? Prefer to use some standard library function.

I plan to use

substring, and find_last_of

Adam Lee
  • 24,710
  • 51
  • 156
  • 236
  • 3
    Have you tried anything at all – Ed Heal Jan 03 '15 at 08:29
  • I am trying to use some std::string method, but wondering if have the wrong direction at the beginning – Adam Lee Jan 03 '15 at 08:30
  • Especially I would like to avoid Boost library, maybe. I know boost may support path method. – Adam Lee Jan 03 '15 at 08:31
  • stl doesn't have anything to handle file paths. Boost does. If you can't use boos, you must do it yourself. Shouldn't be very difficult. – bolov Jan 03 '15 at 08:32
  • you may look at this answer: http://stackoverflow.com/a/3071694/2082964 – Chris Maes Jan 03 '15 at 08:35
  • You've answered your own question. – sgtHale Jan 03 '15 at 08:36
  • @sgtHale - If you look at the timings he has added to the question my answer! – Ed Heal Jan 03 '15 at 08:39
  • I answered the question. You added a comment and then modified your question to include my answer. The history is there for all to see. – Ed Heal Jan 03 '15 at 08:45
  • @Ed Based on your answer and time history, you don't think I know how to use find_last_of as a try, please respect the OP in the future. – Adam Lee Jan 03 '15 at 08:47
  • std::size_t i = str.rfind('/'); – Marichyasana Jan 03 '15 at 08:51
  • @Ed, please be professional like Chris; If you think it is a duplicate, just point out. – Adam Lee Jan 03 '15 at 08:51
  • Adam - I wrote an answer - you then modified the question to include my answer. Sees rather odd. I note that you have deleted your comment to my answer – Ed Heal Jan 03 '15 at 08:53
  • @Ed, please note, I am not writing find_last_of initially in the question (the added later) does not imply "I saw your answer, then based on your answer, modified my question"; this is YOUR logic only. I know several ways to try long time ago, but want to avoid unnecessary effort if std provides boost provided now. – Adam Lee Jan 03 '15 at 08:59
  • @Ed, I deleted my comment to you since I don't think you have patience to discuss some interesting questions. I only discussed interesting questions with professional answerers. Hopefully you can be one in the future. – Adam Lee Jan 03 '15 at 09:00

3 Answers3

1

Use find_last_of - http://www.cplusplus.com/reference/string/string/find_last_of/

Along with substr should conjecture up a solution for you

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
0

You can try the following:

std::string path = "/a/b/c/text.txt";
size_t lastSlash = path.rfind("/");
if (lastSlash != std::string::npos){
    std::string filename = path.substr(lastSlash + 1);
    std::string folder = path.substr(0, lastSlash);
}

Note that this works only for forward slashes as it is.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
bweber
  • 3,772
  • 3
  • 32
  • 57
  • Personally, I prefer to using find_last_of, since it covers "/" and "\" – Adam Lee Jan 03 '15 at 10:22
  • Why not just cover the appropriate one depending on the platform. – Ed Heal Jan 03 '15 at 10:29
  • Ok, you can do that. I just realized they have an example basically identical to mine on cplusplus.com using find_last_of: http://www.cplusplus.com/reference/string/string/find_last_of/ Some platforms (like Windows) use both. – bweber Jan 03 '15 at 10:30
-2

Based on the duplication(stackoverflow.com/a/3071694/2082964), I think the following solve the question,

Please note , depends on you need the trailing / or not; for my question, I need, so I modified a little bit.

 // string::find_last_of
    #include <iostream>
    #include <string>
    using namespace std;

    void SplitFilename (const string& str)
    {
      size_t found;
      cout << "Splitting: " << str << endl;
      found=str.find_last_of("/\\");
      cout << " folder: " << str.substr(0,found+1) << endl;
      cout << " file: " << str.substr(found+1) << endl;
    }

    int main ()
    {
      string str1 ("/usr/bin/man");
      string str2 ("c:\\windows\\winhelp.exe");

      SplitFilename (str1);
      SplitFilename (str2);

      return 0;
    }
Adam Lee
  • 24,710
  • 51
  • 156
  • 236
  • You should perform error checking on the return value from `find_last_of` – Praetorian Jan 03 '15 at 09:20
  • @Praetorian, what do you mean here? If find_last_of does not find, it will return -1, right? – Adam Lee Jan 03 '15 at 09:23
  • It returns `string::npos` (which is -1). If that happens the subsequent `substr` calls will return incorrect results. Well, maybe incorrect. The *folder* substring will be empty, and the *file* substring will be the entire input, which may or may not be the behavior you want. – Praetorian Jan 03 '15 at 09:28
  • It is still OK I think. If found = -1, folder is str.substr(0,0) = "", which is expected, any more comments? – Adam Lee Jan 03 '15 at 09:31
  • Do you mean I should use std::string::size_type , rather than size_t? – Adam Lee Jan 03 '15 at 09:34
  • 1
    You should, but that's not what I meant. I edited my earlier comment to explain why I thought it might not be the result you want, but it looks like it is, so your solution works. – Praetorian Jan 03 '15 at 09:36
  • Thanks for pointing this out. In this case, it happens to be what I need; in other cases, I think you are totally right, I should check std::npos case. – Adam Lee Jan 03 '15 at 09:39
  • @Praerorian, would you mind edit the answer if you think so? – Adam Lee Jan 03 '15 at 09:40
  • 1
    Is this a cut'n'paste from http://www.cplusplus.com/reference/string/string/find_last_of/ ? – Ed Heal Jan 03 '15 at 10:36