68

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!

Jack Farrow
  • 737
  • 1
  • 7
  • 6
  • 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. – twain249 Apr 18 '12 at 22:53
  • `std::string var = std::string("sometext") + somevar + "sometext" + somevar;` – David Schwartz Nov 11 '17 at 20:28
  • as [@yury's solution shows you can also use printf style](https://stackoverflow.com/a/20630764/52074) API with `boost::format`. – Trevor Boyd Smith Apr 25 '18 at 17:09

8 Answers8

91

Have you considered using stringstreams?

#include <string>
#include <sstream>

std::ostringstream oss;
oss << "sometext" << somevar << "sometext" << somevar;
std::string var = oss.str();
mgiuffrida
  • 3,299
  • 1
  • 26
  • 27
48

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

std::string var = "sometext" + std::to_string(somevar) + "sometext" + std::to_string(somevar);  
David Rinck
  • 6,637
  • 4
  • 45
  • 60
35
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;
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 1
    ...assuming that *type* of `somevar` is on the `operator +(*type*)` list. – mip Apr 18 '12 at 23:05
  • @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.) – David Schwartz Apr 18 '12 at 23:06
14

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

#include <format>

auto var = std::format("sometext {} sometext {}", somevar, somevar);
alkino
  • 760
  • 6
  • 15
7

You can also use sprintf:

char str[1024];
sprintf(str, "somtext %s sometext %s", somevar, somevar);
QuantumBlack
  • 1,549
  • 11
  • 27
  • 3
    This isn't very safe though. The additional complexity of making it safe probably makes it not a very good choice. – David Schwartz Apr 18 '12 at 23:07
  • `snprintf()` would be a better choice. `snprintf(str, 1024, "somtext %s sometext %s", somevar, somevar);` – mip Apr 18 '12 at 23:11
  • 2
    This isn't safe, but *too* handy in comparision with bulky std::string & ostringstream. – Yury Dec 17 '13 at 09:44
3

See also boost::format:

#include <boost/format.hpp>

std::string var = (boost::format("somtext %s sometext %s") % somevar % somevar).str();
Yury
  • 3,000
  • 2
  • 24
  • 24
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

William Banks
  • 79
  • 1
  • 7
0

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.

Autex
  • 307
  • 2
  • 12