C++ Split String Every X Characters

10,053

Solution 1

This will split a string into a vector. If there aren't an even number of splits, it will add the extra characters to the end.

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;
}

Solution 2

The heart of the algorithm really comes down to the following two lines.

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

Also, you should pass the string by const reference.

Solution 3

Using that std::string is a collection of char, a simple implementation could be :

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

Solution 4

Change the way that you are calculating the vector size:

int size = (s.length() - 1) / l + 1;

This is equivalent to the ceiling of the input string length divided by the input length.

BTW, the int(s.length() / l) casting is useless, since both operands are integers.


Finally, use this size inside the loop:

for (int i=0; i<size; i++)
Share:
10,053
Igor
Author by

Igor

Updated on July 28, 2022

Comments

  • Igor
    Igor almost 2 years

    I am trying to write a function that takes a string, and splits every X number of characters:

    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;
    }
    

    For example, If I called DIFSplitStringByNumber("hello!", 2), I should get a vector containing:

    [0] he
    [1] ll
    [2] o!
    

    However, it only seems to get the first two results (the vector size is 2), and when I do something like DIFSplitStringByNumber("hello", 2), it crashes, presumably because its trying to access an array index that doesn't exist (it expects 6 characters, but there are only 5). Is there a simpler way to do this?

  • Igor
    Igor over 9 years
    It works, but doesn't seem to be as fast as millsj's solution.