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" |
但是,我的代码为第一个示例提供了
有人能帮我吗?这是我的代码:
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; } |