将字符串拆分为向量c ++

splitting string into vector c++

我编写了一个简单的代码,将字符串从每个"/"中分离出来,并存储到向量中。我的字符串可能以/或不是开头,definetelly将以/结尾。例如,如果我的字符串是:

1
2
3
4
5
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"

但是,我的代码为第一个示例提供了<"","home","desktop","test","">,并且第二个例子为<"..","folder1","folder2","..","pic.pdf","">

有人能帮我吗?这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#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;
    }


}


C++字符串工具包库(Strtk)对您的问题有以下解决方案:

http://www.codeproject.com/articles/23198/c-string-toolkit-strtk-tokenizer


以下更改可能有帮助:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}


在代码中要做的一些事情可以解决这个问题,可能会有一个更好更优雅的解决方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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;
    }        
}

编辑:清除了代码一点,现在可以删除添加最后一个索引部分。

编辑2:

一个看起来更优雅的解决方案可能是删除NCharCounter并使用拆分索引。如果第一个字符不是("/",则可以将第一个值存储为"-1";如果不是("/",则存储为"0")。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    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);
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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;
}