2009-05-20 232 views
8

我是編程新手。我一直試圖用C++函數在給定參數爆炸字符串的內容轉換爲字符串數組,例如:如何將一個字符串通過分隔符分割成一個數組?

string str = "___this_ is__ th_e str__ing we__ will use__"; 

應返回字符串數組:

cout << stringArray[0]; // 'this' 
cout << stringArray[1]; // ' is' 
cout << stringArray[2]; // ' th' 
cout << stringArray[3]; // 'e str' 
cout << stringArray[4]; // 'ing we' 
cout << stringArray[5]; // ' will use' 

我可以令牌化該字符串很好,但對我來說最難的部分是我如何指定stringArray中的元素數量,然後將其分配給當前字符串toke以及如何從函數返回stringArray。

有人會告訴我如何編寫函數?

編輯1:我不一定需要結果在字符串數組中,只是任何容器,我可以作爲一種常規變量與某種索引調用。

+0

功課,或許?沒問題,當然,但我從回答作業問題的人羣不同... – dmckee 2009-05-20 20:59:53

+0

重複:http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c – lothar 2009-05-20 21:08:43

+0

@Iharhar這裏的答案似乎更有效率。 – Arnthor 2011-10-16 14:49:44

回答

10

這是我在這個使用向量和字符串的第一次嘗試:

vector<string> explode(const string& str, const char& ch) { 
    string next; 
    vector<string> result; 

    // For each character in the string 
    for (string::const_iterator it = str.begin(); it != str.end(); it++) { 
     // If we've hit the terminal character 
     if (*it == ch) { 
      // If we have some characters accumulated 
      if (!next.empty()) { 
       // Add them to the result vector 
       result.push_back(next); 
       next.clear(); 
      } 
     } else { 
      // Accumulate the next character into the sequence 
      next += *it; 
     } 
    } 
    if (!next.empty()) 
     result.push_back(next); 
    return result; 
} 

但願這給你某種如何去這個想法的。在您的例子字符串,返回與此測試代碼正確的結果:

int main (int, char const **) { 
    std::string blah = "___this_ is__ th_e str__ing we__ will use__"; 
    std::vector<std::string> result = explode(blah, '_'); 

    for (size_t i = 0; i < result.size(); i++) { 
     cout << "\"" << result[i] << "\"" << endl; 
    } 
    return 0; 
} 
1

如果你堅持做stringArray數組作爲oppossed到std::vector<>(這是做正確的事),你必須要麼:

  1. 做兩遍(一數,你看)
  2. 你自己實現一個動態數組。

使用矢量更容易vector::push_back()追加新的東西到最後。所以:

vector* explode(string s){ 
    vector<string> *v = new vector<string> 
    //... 
    // in a loop 
    v->push_back(string_fragment); 
    //... 
    return v; 
} 

留下的完整性所有後則不需要。

要返回使用char **的字符串數組。

正如

char ** explode(const char *in){ 
    ... 

} 

BTW--如何調用函數知道有多少元素的返回數組中?你也必須解決這個問題。使用std::vector<>,除非受到外力的限制...

+0

v-> push_back(string_fragment); – ralphtheninja 2009-05-20 21:11:15

1

您可以使用字符串(std::vector<std::string>)的向量,使用push_back將每個令牌附加到它,然後從您的tokenize函數中返回它。

1

使用std :: vector作爲動態數組,並將其作爲結果返回。

1

也許你應該使用列表而不是數組。這樣你就不需要提前知道元素的數量。你也可以考慮使用STL容器。

8

使用STL(抱歉,沒有編譯器未測試)

#include <vector> 
#include <string> 
#include <sstream> 

int main() 
{ 
    std::vector<std::string> result; 

    std::string str = "___this_ is__ th_e str__ing we__ will use__"; 

    std::stringstream data(str); 

    std::string line; 
    while(std::getline(data,line,'_')) 
    { 
     result.push_back(line); // Note: You may get a couple of blank lines 
           // When multiple underscores are beside each other. 
    } 
} 

//或定義令牌

#include <vector> 
#include <string> 
#include <iterator> 
#include <algorithm> 
#include <sstream> 

struct Token: public std::string // Yes I know this is nasty. 
{         // But it is just to demosntrate the principle.  
}; 

std::istream& operator>>(std::istream& s,Token& t) 
{ 
    std::getline(s,t,'_'); 

    // *** 
    // Remove extra '_' characters from the stream. 
    char c; 
    while(s && ((c = s.get()) != '_')) {/*Do Nothing*/} 
    if (s) 
    { 
     s.unget(); // Put back the last char as it is not '_' 
    } 
    return s; 
} 

int main() 
{ 
    std::vector<std::string> result; 

    std::string str = "___this_ is__ th_e str__ing we__ will use__"; 

    std::stringstream data(str); 

    std::copy(std::istream_iterator<Token>(data), 
       std::istream_iterator<Token>() 
       std::back_inserter(result) 
      ); 
} 
0

等到你的數據結構類,然後用鏈表進行編碼。如果它是爲了作業而做的,那麼你可能能夠逃脫,只是啓動數組非常大。

0

下面的代碼:

template <typename OutputIterator> 
int explode(const string &s, const char c, OutputIterator output) { 
    stringstream data(s); 
    string line; 
    int i=0; 
    while(std::getline(data,line,c)) { *output++ = line; i++; } 
    return i; 
} 

int main(...) { 
    string test="H:AMBV4:2:182.45:182.45:182.45:182.45:182.41:32:17700:3229365:201008121711:0"; 
    cout << test << endl; 
    vector<string> event; 
**This is the main call** 
    int evts = explode(test,':', back_inserter(event)); 
    for (int k=0; k<evts; k++) 
    cout << event[k] << "~"; 
    cout << endl; 
} 

輸出

H:AMBV4:2:182.45:182.45:182.45:182.45:182.41:32:17700:3229365:201008121711:0 
H~AMBV4~2~182.45~182.45~182.45~182.45~182.41~32~17700~3229365~201008121711~0~ 
2

它爲我的作品:

#include <iostream> 
#include <vector> 
#include <string> 

using namespace std; 

vector<string> explode(const string &delimiter, const string &explodeme); 

int main(int argc, char *argv[]) 
{ 
    string str = "I have a lovely bunch of cocoa nuts"; 
    cout<<str<<endl; 
    vector<string> v = explode(" ", str); 
    for(int i=0; i<v.size(); i++) 
     cout <<i << " ["<< v[i] <<"] " <<endl; 
} 

vector<string> explode(const string &delimiter, const string &str) 
{ 
    vector<string> arr; 

    int strleng = str.length(); 
    int delleng = delimiter.length(); 
    if (delleng==0) 
     return arr;//no change 

    int i=0; 
    int k=0; 
    while(i<strleng) 
    { 
     int j=0; 
     while (i+j<strleng && j<delleng && str[i+j]==delimiter[j]) 
      j++; 
     if (j==delleng)//found delimiter 
     { 
      arr.push_back( str.substr(k, i-k)); 
      i+=delleng; 
      k=i; 
     } 
     else 
     { 
      i++; 
     } 
    } 
    arr.push_back( str.substr(k, i-k)); 
    return arr; 
} 

來源:http://www.zedwood.com/article/106/cpp-explode-function

0

這是我煮熟的代碼(完整)。對於某些需求相同的用戶可能會有用。

#include <string> 
#include <iostream> 
#include <sstream> 
#include <vector> 
using namespace std; 

int main(){ 
     std::string s = "scott:tiger:mushroom"; 
     std::string delimiter = ":"; 

     std::vector<std::string> outputArr; 
     size_t pos = 0; 
     std::string token; 
     while ((pos = s.find(delimiter)) != std::string::npos) { 
      token = s.substr(0, pos); 
      s.erase(0, pos + delimiter.length()); 
      outputArr.push_back(token); 
     } 
     outputArr.push_back(s); 

     // Printing Array to see the results 
     std::cout<<"====================================================================================\n"; 
     for (int i=0;i<outputArr.size();i++){ 
       std::cout<<outputArr[i]<<"\n"; 
     } 
     std::cout<<"====================================================================================\n"; 
} 

乾杯!

0

我認爲我寫了一個更簡單的解決方案。

std::vector<std::string> explode(const std::string& string, const char delimiter) { 

std::vector<std::string> result; 
unsigned int start = 0, pos = 0; 

while (pos != string.length()) { 
    if (string.at(pos) == delimiter || pos + 1 == string.length()) { 
     unsigned int size = (pos - start) + ((pos + 1) == string.length() ? 1 : 0); 
     if (size != 0) { // Make this 'if' as a option? like a parameter with removeEmptyString? 
      result.push_back(string.substr(start, size)); 
     } 
     start = pos + 1; 
    } 
    pos++; 
} 

return std::move(result); 

}

0

這爲我工作:

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

using namespace std; 

vector<string> split(string str, char delimiter) { 
    vector<string> internal; 
    stringstream ss(str); // Turn the string into a stream. 
    string tok; 

    while(getline(ss, tok, delimiter)) { 
    internal.push_back(tok); 
    } 

    return internal; 
} 

int main(int argc, char **argv) { 
    string myCSV = "one,two,three,four"; 
    vector<string> sep = split(myCSV, ','); 

    // If using C++11 (which I recommend) 
    /* for(string t : sep) 
    * cout << t << endl; 
    */ 

    for(int i = 0; i < sep.size(); ++i) 
    cout << sep[i] << endl; 
} 

來源:http://code.runnable.com/VHb0hWMZp-ws1gAr/splitting-a-string-into-a-vector-for-c%2B%2B

相關問題