2011-07-11 159 views
-1

我想拆分一個包含兩個由「|」分隔的「字符串」的字符數組,變成兩個字符。將字符串拆分爲兩個字符數組

這是我的示例代碼。

void splitChar(const char *text, char *text1, char *text2) 
{ 
    for (;*text!='\0' && *text != '|';) *text1++ = *text++; 
    *text1 = '\0'; 
    for (;*++text!='\0';) *text2++ = *text; 
    *text2 = '\0'; 
} 

int main(int argc, char* argv[]) 
{ 

    char *text = "monday|tuesday", text1[255], text2 [255]; 
    splitChar (text, text1, text2); 
    return 0; 
} 

我有兩個問題:

  1. 如何進一步提高用C代碼(例如重寫它在1週期)。

  2. 如何用C++重寫這段代碼?

+3

你的意思是「字符串」,而不是「字符」...... –

回答

1

對於A,使用內部庫:

void splitChar(const char *text, char *text1, char *text2) 
{ 
    int len = (strchr(text,'|')-text)*sizeof(char); 
    strncpy(text1, text, len); 
    strcpy(text2, text+len+1); 
} 
+1

爲了正確,'len'的確應該是'ptrdiff_t'類型。 – Hugh

2

如果你婉把它寫在C++,使用STL

string s = "monday|tuesday"; 
int pos = s.find('|'); 
if(pos == string::npos) 
    return 1; 
string part1 = s.substr(0, pos); 
string part2 = s.substr(pos+1, s.size() - pos); 
+1

**不要** ** pos == -1'。使用'pos == std :: string :: npos' –

1

我不知道A),但是對於B),下面是我在各種項目中使用的實用程序庫的一種方法,顯示如何將任意數量的單詞分成一個vector。它的編碼是爲了在空間和標籤上分割,但如果你願意的話,你可以把它作爲附加參數傳入。它返回的單詞數分裂:

unsigned util::split_line(const string &line, vector<string> &parts) 
{ 
    const string delimiters = " \t"; 
    unsigned count = 0; 
    parts.clear(); 

    // skip delimiters at beginning. 
    string::size_type lastPos = line.find_first_not_of(delimiters, 0); 

    // find first "non-delimiter". 
    string::size_type pos = line.find_first_of(delimiters, lastPos); 

    while (string::npos != pos || string::npos != lastPos) 
    { 
     // found a token, add it to the vector. 
     parts.push_back(line.substr(lastPos, pos - lastPos)); 
     count++; 

     // skip delimiters. Note the "not_of" 
     lastPos = line.find_first_not_of(delimiters, pos); 

     // find next "non-delimiter" 
     pos = line.find_first_of(delimiters, lastPos); 
    } 

    return count; 
} 
0

我找到了一個破壞性的分裂是性能和靈活性的最佳平衡。

void split_destr(std::string &str, char split_by, std::vector<char*> &fields) { 
    fields.push_back(&str[0]); 
    for (size_t i = 0; i < str.size(); i++) { 
     if (str[i] == split_by) { 
      str[i] = '\0'; 
      if (i+1 == str.size()) 
       str.push_back('\0'); 
      fields.push_back(&str[i+1]); 
     } 
    } 
} 

然後一個非破壞性的版本爲lazies。

template<typename C> 
    void split_copy(const std::string &str_, char split_by, C &container) { 
     std::string str = str_; 
     std::vector<char*> tokens; 
     parse::split_destr(str, split_by, tokens); 
     for (size_t i = 0 ; i < tokens.size(); i++) 
      container.push_back(std::string(tokens[i])); 
    } 

我在這個時候來到之類的boost ::標記者落空對他們的臉處理GB +大小的文件。

0

我道歉提前回答我的答案:)沒有人應該在家裏試試這個。

回答你的問題的第一部分。

A]如何在C語言中進一步改進此代碼(例如,將其重寫爲1 for循環)。

該算法的複雜性取決於'|'的位置在哪裏,在字符串中,但這個例子只適用於由'|'分隔的兩個字符串。您可以稍後對其進行更改,以便更進一步。

#include <stdio.h> 

void splitChar(char *text, char **text1, char **text2) 
{ 
    char * temp = *text1 = text; 
    while (*temp != '\0' && *temp != '|') temp++; 

    if (*temp == '|') 
    { 
     *temp ='\0'; 
     *text2 = temp + 1; 
    } 
} 

int main(int argc, char* argv[]) 
{ 

    char text[] = "monday|tuesday", *text1,*text2; 
    splitChar (text, &text1, &text2); 
    printf("%s\n%s\n%s", text,text1,text2); 
    return 0; 
} 

這工作,因爲C風格的數組使用空字符來終止字符串。由於使用「」初始化字符串將在末尾添加空字符,因此您只需替換「|」的出現即可。與空字符並將其他字符指針指派給'|'後面的下一個字節。

您必須確保使用[]初始化原始字符串,因爲這會告知編譯器爲您的字符數組分配存儲空間,其中char *可能會在無法更改的內存靜態區域中初始化該字符串。