0

I am faced with a simple yet complex challenge today.

In my program, I wish to insert a - character every three characters of a string. How would this be accomplished? Thank you for your help.

#include <iostream>

int main()
{
    std::string s = "thisisateststring";

    // Desired output: thi-sis-ate-sts-tri-ng
    std::cout << s << std::endl;
    return 0;
}
Koi
  • 87
  • 1
  • 9
  • 3
    What have you tried? How did that work? How didn't that work? And please read [the help pages](http://stackoverflow.com/help), especially the sections named ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also please [take the tour](http://stackoverflow.com/tour) and [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask). – Some programmer dude Apr 10 '18 at 16:28
  • 1
    Please attempt a solution before posting the question. – edtheprogrammerguy Apr 10 '18 at 16:29
  • @edtheprogrammerguy Before creating this post I referred to [this post](https://stackoverflow.com/questions/3223302/c-insert-char-to-a-string), but I am unsure of how to implement this into my code. – Koi Apr 10 '18 at 16:33

6 Answers6

2

There is no need to "build a new string".

Loop a position iteration, starting at 3, incrementing by 4 with each pass, inserting a - at the position indicated. Stop when the next insertion point would breach the string (which has been growing by one with each pass, thus the need for the 4 slot skip):

#include <iostream>
#include <string>

int main()
{
    std::string s = "thisisateststring";

    for (std::string::size_type i=3; i<s.size(); i+=4)
        s.insert(i, 1, '-');

    // Desired output: thi-sis-ate-sts-tri-ng
    std::cout << s << std::endl;
    return 0;
}

Output

thi-sis-ate-sts-tri-ng
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • `insert()` scales pretty badly - you'll end up copying _O(n²)_ characters, for a _n_-character string. – Toby Speight Apr 10 '18 at 16:48
  • @Toby Speight For most common string sizes that's probably irrelevant. Much more important is the fact that it's a simple and readable solution. – Jesper Juhl Apr 10 '18 at 16:58
1

A general (and efficient) approach is to build a new string by iterating character-by-character over the existing one, making any desired changes as you go. In this case, every third character you can insert a hyphen:

std::string result;
result.reserve(s.size() + s.size() / 3);
for (size_t i = 0; i != s.size(); ++i) {
    if (i != 0 && i % 3 == 0)
        result.push_back('-');
    result.push_back(s[i]);
}
Cameron
  • 96,106
  • 25
  • 196
  • 225
1

just take an empty string and append "-" at every count divisible by 3

#include <iostream>

int main()
{
    std::string s = "thisisateststring";
    std::string res="";
    int count=0;
    for(int i=0;i<s.length();i++){
        count++;
        res+=s[i];
        if(count%3==0){
            res+="-";
        }
    }
    std::cout << res << std::endl;
    return 0;
}

output

thi-sis-ate-sts-tri-ng
Roushan
  • 4,074
  • 3
  • 21
  • 38
0

Simple. Iterate the string and build a new one

Copy each character from the old string to the new one and every time you've copied 3 characters add an extra '-' to the end of the new string and restart your count of copied characters.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
0

Like 99% problems with text, this one can be solved with a regular expression one-liner:

std::regex_replace(input, std::regex{".{3}"}, "$&-")

However, it brings not one, but two new problems:

  • it is not a very performant solution
  • regex library is huge and bloats resulting binary

So think twice.

flapenguin
  • 380
  • 1
  • 3
  • 16
  • Although I actually think [regular expressions](https://blog.codinghorror.com/regular-expressions-now-you-have-two-problems/) are fabulous, I find this Jamie Zawinski quip funny: Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. – Eljay Apr 10 '18 at 17:40
0

You could write a simple functor to add the hyphens, like this:

#include <iostream>

struct inserter
{
    unsigned n = 0u;
    void operator()(char c)
    {
        std::cout << c;
        if (++n%3 == 0) std::cout << '-';
    }
};

This can be passed to the standard for_each() algorithm:

#include <algorithm>

int main()
{
    const std::string s = "thisisateststring";
    std::for_each(s.begin(), s.end(), inserter());
    std::cout << std::endl;
}

Exercise: extend this class to work with different intervals, output streams, replacement characters and string types (narrow or wide).

Toby Speight
  • 27,591
  • 48
  • 66
  • 103