Search code examples
c++stringconcatenation

C++: How to concatenate a variable between strings literals?


I need a way to get this PHP behaviour in C++:

$foo = "PHP";
$bar = "this is a " . $foo . " example.";

Is there something close to that, or do I have to do lots of strcat?


Solution

  • Easy enough with std::string:

    std::string foo = "C++";
    auto bar = "this is a " + foo + " example.";
    

    Just make sure one of the first two operands is a std::string, not both const char * or something.


    As noted below, this result is being used in CreateProcess as a char * (LPSTR) argument. If the argument was const char *, c_str() would be perfectly acceptable to pass in. However, it is not, which means you should assume it modifies the string. MSDN says this:

    The Unicode version of this function, CreateProcessW, can modify the contents of this string.

    Since this is char *, it's evidently using CreateProcessA, so I'd say a const_cast<char *> should work, but it's better to be safe.

    You have two main options, one for C++11 and later, and one for pre-C++11.

    C++11

    std::string's internal buffer is now guaranteed to be contiguous. It's also guaranteed to be null-terminated. That means you can pass a pointer to the first element:

    CreateProcess(..., &str[0], ...);
    

    Make sure the function only overwrites indices within [0, size()) in the internal array. Overwriting the guaranteed null-terminator is not good.

    C++03

    std::string is not guaranteed to be contiguous or null-terminated. I find it best to make a temporary std::vector, which guarantees the contiguous part, and pass a pointer to its buffer:

    std::vector<char> strTemp(str.begin(), str.end());
    strTemp.push_back('\0');
    CreateProcess(..., &strTemp[0], ...);
    

    Also note MSDN again:

    The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides the original string into two strings for internal processing.

    That seems to suggest that the null-terminator here isn't necessary, but there's no size parameter, so I'm not completely sure.