77

I'm trying to do something very simple and yet, after an hour of so of searching a I can't find a suitable answer so I must be missing something fairly obvious.

I'm trying to dynamically create filenames for use with ifstream. Whilst I understand various methods are available of doing this, I have settled on creating a std::string, and the using stringname.c_str to convert to const.

The problem is however that I need to create the string with a mix of variables and predefined text values. I'm getting compiler errors, so this must be a syntax issue.

Pseudo

std::string var = "sometext" + somevar + "sometext" + somevar;

Thanks!

3
  • 4
    if it's a syntax error you should post the actual code then we can tell you want the syntax error is (and why it's wrong) and you'll learn more than if we just give you the correct syntax. Commented Apr 18, 2012 at 22:53
  • std::string var = std::string("sometext") + somevar + "sometext" + somevar; Commented Nov 11, 2017 at 20:28
  • as @yury's solution shows you can also use printf style API with boost::format. Commented Apr 25, 2018 at 17:09

8 Answers 8

102

Have you considered using stringstreams?

#include <string>
#include <sstream>

std::ostringstream oss;
oss << "sometext" << somevar << "sometext" << somevar;
std::string var = oss.str();
Sign up to request clarification or add additional context in comments.

3 Comments

Exactly + std::ostringstream would be sufficient.
Thanks @eli - This was the method which I had initially attempted without any luck, but is now working! Can you explain what ss.str() is doing at all?
ss.str() is extracting the contents of the stringstream.
53

In C++11 you can use std::to_string:

std::string var = "sometext" + std::to_string(somevar) + "sometext" + std::to_string(somevar);  

Comments

38
std::string var = "sometext" + somevar + "sometext" + somevar;

This doesn't work because the additions are performed left-to-right and "sometext" (the first one) is just a const char *. It has no operator+ to call. The simplest fix is this:

std::string var = std::string("sometext") + somevar + "sometext" + somevar;

Now, the first parameter in the left-to-right list of + operations is a std::string, which has an operator+(const char *). That operator produces a string, which makes the rest of the chain work.

You can also make all the operations be on var, which is a std::string and so has all the necessary operators:

var = "sometext";
var += somevar;
var += "sometext";
var += somevar;

2 Comments

...assuming that type of somevar is on the operator +(*type*) list.
@doc Yep. Otherwise, you'll have to add some code around somevar to make it work. For example, if it's an int, you can use Boost::lexical_cast to make it a string. (Or, in that case, the stringstream solution might be better.)
15

The new way to do with c++20 is using format.

#include <format>

auto var = std::format("sometext {} sometext {}", somevar, somevar);

Comments

7

You can also use sprintf:

char str[1024];
sprintf(str, "somtext %s sometext %s", somevar, somevar);

5 Comments

This isn't very safe though. The additional complexity of making it safe probably makes it not a very good choice.
snprintf() would be a better choice. snprintf(str, 1024, "somtext %s sometext %s", somevar, somevar);
This isn't safe, but too handy in comparision with bulky std::string & ostringstream.
@DavidSchwartz Why is it not safe? Do you mean that it is prone to cyberattacks? If yes, how so? Could you elaborate, please?
@ViníciusQueiroz What if the formatted output exceeds 1023 characters and overflows str?
4

See also boost::format:

#include <boost/format.hpp>

std::string var = (boost::format("somtext %s sometext %s") % somevar % somevar).str();

Comments

2

Since c++14 you can use the std::string operator""s from std::string_literals

#include <string>
using namespace std::string_literals;
std::string var = "sometext"s + somevar + "sometext"s + somevar;

The compiler will add a std::string in place of the literal, and as such you can use the "+" operator with it.

1 Comment

Looks greatly underrated. The new C++20 format thing looks like an overkill for such a simple task, while this solution is simple enough. I am just wondering are there any caveats with using std::string_literals?
0

You could have something like:

#define Compose(...) ComposeFn({ __VA_ARGS__ })

std::string ComposeFn(std::initializer_list<std::string> strList) {
    std::ostringstream ss;
    for(std::string str : strList) {
        ss << str;
    }
    return ss.str();
}

And then use it like:

int errcode = 404;
std::cout << Compose("[ERROR]: (", errcode, ") doesn't exist") << std::endl;

The Compose macro is just to avoid using the curly brackets. You could also use a variadic function, but eh

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.