将字符数组拆分为两个字符数组

Split array of chars into two arrays of chars

本文关键字:字符 数组 两个 拆分      更新时间:2023-10-16

我想将一个包含两个以'|'分隔的"字符串"的字符数组拆分为两个字符数组。

下面是我的示例代码。

void splitChar(const char *text,  char *text1, char *text2)
{
   for (;*text!='' && *text != '|';) *text1++ = *text++;
   *text1 = '';
   for (;*++text!='';) *text2++ = *text;
   *text2 = '';
}
int main(int argc, char* argv[])
{
    char *text = "monday|tuesday", text1[255], text2 [255];
    splitChar (text, text1, text2);
    return 0;
}

我有两个问题:

  1. 如何在C中进一步改进此代码(例如将其重写为1 for cycle)

  2. 如何在c++中重写此代码?

如果您想用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);

对于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);
}

我不知道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;
}

可能这些解决方案之一将工作:在c++中拆分字符串?

看看下面给出的例子:strtok, wcstock, _mbstock

我发现破坏性分割是性能和灵活性的最佳平衡。

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] = '';
            if (i+1 == str.size())
                str.push_back('');
            fields.push_back(&str[i+1]);
        }
    }
}

然后是懒人的非破坏性版本。

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::Tokenizer处理gb+大小的文件时,我达到了这个目的。

我提前为我的回答道歉:)任何人都不应该在家里尝试这个。

回答你问题的第一部分。

A]如何在C中进一步改进此代码(例如将其重写为1 for cycle)

这个算法的复杂性将取决于'|'在字符串中的位置,但这个例子只适用于由'|'分隔的两个字符串。您以后可以很容易地修改它,以获得更多。

#include <stdio.h>
void splitChar(char *text,  char **text1, char **text2)
{
    char * temp = *text1 = text;
    while (*temp != '' && *temp != '|') temp++;
    if (*temp == '|') 
    {
        *temp ='';
        *text2 = temp + 1;
    }
}
int main(int argc, char* argv[])
{
    char text[] = "monday|tuesday", *text1,*text2;
    splitChar (text, &text1, &text2);
    printf("%sn%sn%s", text,text1,text2);
    return 0;
}

之所以有效,是因为c风格的数组使用null字符来终止字符串。由于使用"初始化字符串将在末尾添加一个空字符,因此您所要做的就是将'|'替换为空字符,并将其他char指针赋值给'|'后面的下一个字节。

你必须确保用[]初始化你的原始字符串,因为它告诉编译器为你的字符数组分配存储空间,char *可能会在一个不能改变的静态内存区域初始化字符串