1

As part of my homework assignment, I have to split a char[] by its indices. So for example, the main function looks like:

int main()
{
    char str[] = "A string to be split into given number of parts";

    int split_size;
    cout << "Enter the size of the part: ";
    cin >> split_size;

    int size = sizeof(str) / sizeof(str[0]);

    SplitString(str, split_size, size);


    int wait;
    cin >> wait; 
    return 0;
}

Then using the function SplitString, the first x elements are printed, new line, then the next.

My first idea, was to use two for loops. One loops through the splits (i.e. if there are 4 splits, the range on this loop is 0 to 3), then the second loops through the split itself, iterating over the array elements.

My SplitString() function looks like this:

void SplitString(char str[], int split_size, int size) {

    int parts = size / split_size;

    for (int i = 0; i < parts; i++) {
        for (int j = 0; j < split_size; j++) {
            j = split_size * i;
            cout << str[j];
        }
        cout << endl; 
    }
}

Is there an easier way to do this? I know in Python, you can use the arr[1:] to grab a range of elements from the array. Is there anything similar in C++? Is there some flaw in my logic? Is there something wrong with my code?

4
  • 1
    What about creating a std::string from the start and end of the range - or even something with std::string_view if you want to avoid the copy. You tagged it as C++ so there is no reason to use character arrays (it's a very C thing to do...) Commented Nov 24, 2019 at 21:28
  • So it's splitting the array by index. As far as I'm aware, str[1] will grab the second word. This needs to be done by character, so it splits every split_size characters. Commented Nov 24, 2019 at 21:31
  • How would str[1] know where the second word starts. A character string has one character at each index so str[1] would be the second character. Commented Nov 24, 2019 at 21:33
  • When I tried using str[1] as a string, with the given string A string to be split into given number of parts!, it returned ` string`. Commented Nov 24, 2019 at 21:38

2 Answers 2

1

cout comes with a write function that takes a pointer and a size argument.

for (int i = 0; i < parts; i++) {
    cout.write (str+i*split_size, split_size)
    cout << endl; 
}

Note that the code above does not check if the string is actually long enough. If the total size is not equal the split_size times a whole number, you will have to add an additional check.

Also, note that this:

int size = sizeof(str) / sizeof(str[0]);

can be written as:

int size = sizeof(str);

instead because the size of a char is always 1.

Sign up to request clarification or add additional context in comments.

2 Comments

This worked perfectly thank you. Now to study all the crazy cin/cout magic!
Very nice, minimal solution: if all is needed is properly formatted output then no data should be copied around. Your suggested range check is in my opinion mandatory though: In order to prevent reads past the end of the string, and in order to output the potentially incomplete last chunk properly.
0

You can use std::string for this. Alternatively, if your compiler supports C++17, you can use std::string_view as the first argument of SplitString to avoid unnecessary copying.

#include <algorithm>
#include <iostream>
#include <string>

void SplitString(std::string s, std::size_t split_size)
{
    while(!s.empty())
    {
        auto size = std::min(split_size, s.size());
        std::cout << s.substr(0, size) << '\n';
        s = s.substr(size, std::string::npos);
    }
}

int main()
{
    char str[] = "A string to be split into given number of parts";

    int split_size = 5;

    SplitString(str, split_size);

    return 0;
}

Live example.

2 Comments

Wow! This is far and away above what is being taught currently in my course, but that is an extremely neat and succinct way to do it. Similarly, as opposed to the other answer, it accounts for a string that is not neatly divisible by the split_size. Thank you.
@satazero check out alternative solutions: coliru.stacked-crooked.com/a/a3230699f85b4bac

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.