C++每隔X个字符拆分字符串

9
我正在尝试编写一个函数,它可以接受一个字符串,并将每X个字符分割一次:
std::vector<std::string> DIFSplitStringByNumber(std::string s, int l)
{
    const char *c = s.c_str();  
    char buffer[l];
    std::vector<std::string> entries;
    entries.reserve(int(s.length() / l) + 1);

    int d = 0;   
    for(int i = 0; i < s.length() - 1;)
    {
        if(d != l)
        {
            buffer[d] = c[i];
            d++;
            i++;
        }
        else
        {
            entries.push_back(std::string(buffer, l));

            //Clear array
            memset(buffer, 0, l);
            d = 0;
        }       
    }

    return entries;
}

例如,如果我调用DIFSplitStringByNumber("hello!", 2),我应该得到一个包含以下内容的向量:
[0] he
[1] ll
[2] o!

然而,它只似乎获得了前两个结果(向量大小为2),当我尝试使用 DIFSplitStringByNumber("hello", 2) 等方式时,它会崩溃,可能是因为它试图访问不存在的数组索引(它期望有6个字符,但实际上只有5个)。有没有更简单的方法来做到这一点?

为什么没有 string::substr 函数? - user2249683
C ++ 中是否允许使用VLA(如char buffer[l])? - barak manos
@barakmanos 在C++14或使用g++编译器,是的。 - Quentin
@barakmanos 我甚至没有意识到那是一种非标准的写法。我想应该改成类似于“char *buffer = new char[l]”这样的形式? - Igor
@Igor:是的,那就是我会用的方法...但如果它对你有效,那么,我能说什么呢 :) ...无论如何,我写了一个答案(下面),建议你如何计算向量的大小。 - barak manos
4个回答

11

算法的核心实际上可以归结为以下两行代码。

for (size_t i = 0; i < s.size(); i += l)
    res.push_back(s.substr(i, l));

此外,您应该通过const引用传递字符串。


它能工作,但似乎不如millsj的解决方案快。 - Igor

6
这将把一个字符串分割成向量。如果没有偶数个分割,它会将额外的字符添加到末尾。
std::vector<std::string> Split(const std::string& str, int splitLength)
{
   int NumSubstrings = str.length() / splitLength;
   std::vector<std::string> ret;

   for (auto i = 0; i < NumSubstrings; i++)
   {
        ret.push_back(str.substr(i * splitLength, splitLength));
   }

   // If there are leftover characters, create a shorter item at the end.
   if (str.length() % splitLength != 0)
   {
        ret.push_back(str.substr(splitLength * NumSubstrings));
   }


   return ret;
}

3

使用std::string作为char的集合,一个简单的实现方法如下:

std::vector<std::string> DIFSplitStringByNumber(const std::string & str, int len)
{
    std::vector<std::string> entries;
    for(std::string::const_iterator it(str.begin()); it != str.end();)
    {
        int nbChar = std::min(len,(int)std::distance(it,str.end()));
        entries.push_back(std::string(it,it+nbChar));
        it=it+nbChar;
    };
    return entries;
}

Live sample


2
改变计算向量大小的方式:
int size = (s.length() - 1) / l + 1;

这相当于将输入字符串长度除以输入长度的上取整。

顺便说一句,int(s.length() / l) 的转换是无用的,因为两个操作数都是整数。


最后,在循环中使用这个大小:

for (int i=0; i<size; i++)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接