How to create a string from two vectors of strings in C++?

Viewed 341

I have two separate vectors of strings:

std::vector<std::string> vectorA;
vectorA.push_back("a1");
vectorA.push_back("\na2");

std::vector<std::string> vectorB;
vectorB.push_back("b1");
vectorB.push_back("b2");

I want to create an std::string vectorOutput which shows the following:

a1 b1
a2 b2

Now, the elements in vector A are defined in one class, while the elements in vector B come from another class and are read after some code logic happens. The vector sizes are identical. I would like to know what is the best way in C++ to create this new vectorOutput string? I was thinking of a loop which iterates over the elements of each vector and appends them to the vectorOutput, like:

for (int i = 0; i < vectorA.size() < i++)
{
    vectorOutput += vectorA[i] + vectorB[i];
}

In my code these vectors have more elements than presented here. Is there another way to achieve this? Perhaps by creating enums or structs?

2 Answers

If you are speaking about efficiency, this is probably not the best way to do it because you will copy the string each time. It could be better to create a long string directly and to replace some of its characters with the strings you want to concatenate :

#include <iostream>
#include <string>

int main() {
    std::string str1 = "stringA";
    int len1 = str1.length();
    std::string str2 = "stringB";
    int len2 = str2.length();
    std::string bigString(256, ' ');          //create a container string 
    bigString.replace(0, len1, str1);         //paste a string within it
    bigString.replace(len1 + 1, len2, str2);  //paste a second string after (with a space to separate)
    
    std::cout << bigString << std::endl;      //=>"stringA stringB           ..."

    //resize it when needed
    bigString.resize(512, ' '); 
}

With the range-v3 library, you could write it like this:

namespace rs = ranges;
namespace rv = ranges::views;
    
auto outputVector = rv::transform(vectorA, vectorB, std::plus{}) 
                  | rv::cache1 
                  | rv::join 
                  | rs::to<std::string>;

This has no loops, and is quite readable. Note that cache1 is needed to make sure that the views returned by views::transform are not dangling.

Here's a demo.

Related