12

I wrote a simple code to split the string from each '/' and store into vector. My string may start with / or not and definetelly will end with /. For example if my string is:

string="/home/desktop/test/" 
I want to <"/","home","desktop","test"> and another example

string="../folder1/folder2/../pic.pdf/" 
I want to store <"..","folder1","folder2","..","pic.pdf"

However, my code gives me <" ","home","desktop","test"," "> for the first example and <"..","folder1","folder2","..","pic.pdf"," "> for the second example

Is there anyone to help me ? Here is my code for this :

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
    string strLine("/cd/desktop/../test/");
    string strTempString;
    vector<int> splitIndices;
    vector<string> splitLine;
    int nCharIndex = 0;
    int nLineSize = strLine.size();

    // find indices
    for(int i = 0; i < nLineSize; i++)
    {
        if(strLine[i] == '/')
            splitIndices.push_back(i);
    }
    splitIndices.push_back(nLineSize); // end index

    // fill split lines
    for(int i = 0; i < (int)splitIndices.size(); i++)
    {
        strTempString = strLine.substr(nCharIndex, (splitIndices[i] - nCharIndex));
        splitLine.push_back(strTempString);
        cout << strTempString << endl;
        nCharIndex = splitIndices[i] + 1;
    }


}
7
  • possible duplicate of Parse (split) a string in C++ using string delimiter (standard C++) Commented Dec 29, 2013 at 13:05
  • 1
    yes, but he want help with he code, rahter than from scratch Commented Dec 29, 2013 at 13:06
  • 1
    It seems you are looking for parsing a filesystem path. Maybe use Boost.filesystem? Commented Dec 29, 2013 at 13:08
  • would a trivial hack do the job? start the first loop at i=1, and stop one char short of the end? Commented Dec 29, 2013 at 13:09
  • @RichardPlunkett How do you know? What if the real problem he's trying to solve is decomposing a path, but he thought that there wasn't an already available solution for that? Commented Dec 29, 2013 at 13:09

4 Answers 4

9

The C++ String Toolkit Library (Strtk) has the following solution to your problem:

http://www.codeproject.com/Articles/23198/C-String-Toolkit-StrTk-Tokenizer

Sign up to request clarification or add additional context in comments.

1 Comment

Library was deleted in 2017
1

Some things to do in the code that should fix this, there might be a better and more elegant solution for this.

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
    string strLine("/cd/desktop/../test/");
    string strTempString;
    vector<int> splitIndices;
    vector<string> splitLine;
    int nCharIndex = 0;
    int nLineSize = strLine.size();

    // find indices
    if(nLineSize!=0 && strLine[0]=='/')
    {
         splitLine.push_back(strLine.substr(0,1));
         nCharIndex++;
    }

    for(int i = 1; i < nLineSize; i++)
    {
        if(strLine[i] == '/')
            splitIndices.push_back(i);
    }

    // fill split lines
    for(int i = 0; i <int(splitIndices.size()); i++)
    {
        strTempString = strLine.substr(nCharIndex, (splitIndices[i] - nCharIndex));
        splitLine.push_back(strTempString);
        nCharIndex = splitIndices[i] + 1;
    }        
}

Edit : Cleaned the code a bit, you can remove the adding the last index part now.

Edit 2:

A possibly more elegant looking solution for this might be by removing the ncharcounter and using your splitting index for that. You can store the first value as '-1' if the first character is not ('/') or as ('0') if it is.

    string strLine("/cd/desktop/../test/");
    string strTempString;
    vector<int> splitIndices;
    vector<string> splitLine;
    int nLineSize = strLine.size();

    // find indices
    splitIndices.push_back(-1);
    if(nLineSize!=0 && strLine[0]=='/')
    {
         splitLine.push_back(strLine.substr(0,1));
         splitIndices[0]=0;
    }             
    for(int i = 1; i < nLineSize; i++)
    {
        if(strLine[i] == '/')
            splitIndices.push_back(i);
    }

    // fill split lines
    for(int i = 1; i <int(splitIndices.size()); i++)
    {
        strTempString = strLine.substr(splitIndices[i-1]+1, (splitIndices[i] - (splitIndices[i-1]+1) ));
        splitLine.push_back(strTempString);
    }        

Comments

1

Following change may help:

if (!strLine.empty() && strLine.back() != '/') {
    splitIndices.push_back(nLineSize); // end index
}
// fill split lines
for(int i = 0; i < (int)splitIndices.size(); i++)
{
    if (splitIndices[i] == 0) {
        splitLine.push_back("/");
    } else {
        strTempString = strLine.substr(nCharIndex, (splitIndices[i] - nCharIndex));
        splitLine.push_back(strTempString);
    }
    nCharIndex = splitIndices[i] + 1;
}

Comments

0
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

int main()
{
    std::string s1 = "/home/desktop/test/";
    std::string s2 = "../folder1/folder2/../pic.pdf/";

    std::vector<std::string> v1;

    std::istringstream is1( s1 );

    std::string t;

    while ( std::getline( is1, t, '/' ) )
    {
        if ( t.empty() ) v1.push_back( "/" );
        else v1.push_back( t );
    }

    for ( const std::string &t : v1 ) std::cout << t << std::endl;

    std::cout << std::endl;

    std::vector<std::string> v2;

    std::istringstream is2( s2 );

    while ( std::getline( is2, t, '/' ) )
    {
        if ( t.empty() ) v2.push_back( "/" );
        else v2.push_back( t );
    }

    for ( const std::string &t : v2 ) std::cout << t << std::endl;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.