11

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;
    }


}
caesar
  • 2,165
  • 9
  • 23
  • 34
  • possible duplicate of [Parse (split) a string in C++ using string delimiter (standard C++)](http://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c) – legends2k Dec 29 '13 at 13:05
  • 1
    yes, but he want help with he code, rahter than from scratch – RichardPlunkett Dec 29 '13 at 13:06
  • 1
    It seems you are looking for parsing a filesystem path. Maybe use [Boost.filesystem](http://www.boost.org/doc/libs/1_50_0/libs/filesystem/doc/reference.html#path-decomposition)? –  Dec 29 '13 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? – RichardPlunkett Dec 29 '13 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? –  Dec 29 '13 at 13:09
  • Would a trivial hack do the job? start the first loop at i=1, and stop one char short of the end? Or just clip empty strings off start/end of final vector – RichardPlunkett Dec 29 '13 at 13:11
  • strtok might be usefuk – gelatine1 Dec 29 '13 at 13:21

4 Answers4

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

Dhayalan Pro
  • 573
  • 1
  • 4
  • 16
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);
    }        
erosenin
  • 992
  • 8
  • 22
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;
}
Jarod42
  • 173,454
  • 13
  • 146
  • 250
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;
}
Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268