Creating single string from array of strings C++

Started by
18 comments, last by Juliean 4 years ago

Answers seem to be all over the place as to the best approach. I just need a simple way to take an array of string values and combine them into one and a way to separate them again to re-insert them into an array. Nothing fancy required.

Basically I just need the proper syntax for joining two strings with some type of separator and the syntax for breaking those strings back up again. I'll handle the looping function outside of the combining function.

Advertisement

I think the thing here is since C++ doesn't offer a built in way to do this, but there are lots of ways to do it your self.

Of special note is that in the general case to join a bunch of strings, and then split them again, you have to consider what if one of the strings actually contains your separator? Or what if the API or other requirements disallow certain elements (e.g. while `std::string` can contain null (0) elements, many `char*` API's can't. And if you want to display your string, many more restrictions). Which then brings you into escaping/encoding.

And again many solutions to this, many languages/schemes use a backslash to handle just the “special” characters (including C/C++ source code itself, but the standard lib has no function to create or parse these…), things like base64 will just encode everything, other schemes like percent encoding (URLs), or enclosing with double quotes (e.g. CSV, which then leads to double double quotes). So no real right choice, if you need to exchange data with one (say JavaScript/JSON) use that, otherwise just pick one.

To merge two or more strings, you could use

std::stringstream str(s1);
str << “|” << s2;

where you replace | with whatever you choose to be the separator, and then use str.str() to get the final string. To break the string apart you use

std::getline(str,s1,"|");
std::getline(str,s2,"|");

and so on for however many strings you put in the stringstream. Also to do this you need to include <string> and <sstream>.

std::stringstream is a bit on the heavy side of things. I would probably just create an std::string itself, preferably in a helper function (and use std::string_view if you have access to C++17):

constexpr std::string_view SEPARATOR = “|”;

std::string concat(std::string_view a, std::string_view b)
{
    std::string result;
    result.reserve(a.size() + b.size() + SEPARATOR.size());
    
    result += a;
    result += SEPARATOR;
    result += b;
    
    return result
}

std::pair<std::string_view, std::string_view> split(std::string_view string)
{
     const auto pos = string.find(SEPARATOR);
     assert(pos != std::wstring::npos);
              
     return
     {
         string.substr(0, pos),
         string.substr(pos + 1);
     };
}

This would require the least amount of allocations possible. I generally only manipulate strings view string_view for that reason. Only thing to keep in mind is that you have to convert to std::string again if you intend to store the split-result while the concated-string might not exist anymore.

Thanks guys. I'm pairing this with blueprints in ue4. I need to store some arrays to send them to a column in my sql db. I'm setting up a custom node for this bit. It occured to me I just need to setup one node technically to separate the strings since I can use append on a foreachloop function to create a single string.

Sometimes people over analyze things, to join several strings.

string first = “jessica”;
string last = “malessik”;
string joinstrings = first + last; // combine them together

to insert stuff between them?

string joinstrings = first + “ ### " + last; // inserts ### between first and last

you can insert a string into a vector like this

vector<string>mystuff(100);
mystuff.insert(mystuff.begin() + 10,first); // inserts first into position 10

I recommend you read,

http://www.cplusplus.com/reference/string/string/ — for string reference

and

http://www.cplusplus.com/reference/vector/vector/ — for vector reference

you can use other types of arrays as well.

How do I tell the function to convert the outputs into FString before returning?
and if I try it this way… apparently it's discarding the output and the compiler isn't having it.

Just a suggestion on tokenizing the string.

#include <iostream>
#include <regex>
#include <string>
#include <vector>

using namespace std;

/*
 * This here is the tokenizer. Splits an input string on “I” characters into an arbitrary number
 * strings appended to the result vector.
 */
void
split_on_sep(string const& src, vector<string>& result)
{
  static const regex  marker{"[^|]+"};
  auto tokens_begin = sregex_iterator{src.begin(), src.end(), marker};
  auto tokens_end = sregex_iterator{};

  for (auto t = tokens_begin; t != tokens_end; ++t)
    result.push_back((*t).str());
}

/*
 * Test it.
 */
int
main()
{
  const  string dbstring{"one|two|three"};
  vector<string> result;
  
  split_on_sep(dbstring, result);

  for (auto const& s: result)
    cout << s << "\n";
}

Here's the output.

$ g++ -std=c++14 -o strs strs.cpp && ./strs
one
two
three

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement