If you haven't got boost then you could use something like:
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
std::vector<std::string> split_into_n( const std::string &input, unsigned n )
{
std::vector<std::string> strings;
auto start_of_string = cbegin( input );
auto characters_left_to_process = input.size();
while( n && characters_left_to_process )
{
auto characters_in_next_string = ( characters_left_to_process + n - 1 ) / n;
strings.push_back( std::string( start_of_string, start_of_string + characters_in_next_string ) );
start_of_string += characters_in_next_string;
characters_left_to_process -= characters_in_next_string;
n--;
}
return strings;
}
auto main()->int
{
std::string s( "123456789abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz" );
auto strings( split_into_n( s, 8 ) );
std::copy( begin( strings ), end( strings ), std::ostream_iterator<std::string>( std::cout, "\n" ) );
}
It's not as fussy as the versions you've written - there's only one loop and fewer local variables. You could eliminate the iterator but when I did the code looked horrible. Generally less locals and less loops makes code a lot easier to write and debug.
[EDIT: Made it so the larger strings are at the beginning of the vector, removing my naive handling non-divisable number of characters, and then removed my naive method of rounding up integer division - thanks to member(some number) for pointing this out]
I'd be interested to see what other people come up with to solve this. While it's a relatively trivial problem it'd be cool to see what simpler methods people have.