Concatenate Multiple "char*"s

I'm having trouble with some code I'm writing that takes user input from a the console and concatenates it with arguments for a java application.

1
2
3
4
5
6
7
  using namespace std;

  char gigs;
  cin >> gigs;

  string str = "java =Xmx" + gigs + "G -Xms" + gigs + "G";
  system(str);


When I compile this using G++, I get this error message:

1
2
3
4
5
  test.cpp: In function 'int main()':
  test.cpp:46:39: error: invalid operands of types 'const char*' and 'cons
  t char [7]' to binary 'operator+'
        string str = "java -Xmx" + gigs + "G -Xms" + gigs + "G"
                      ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~


Any help is greatly appreciated!
Hello @CapnBlackHeart,

The '+' operator is not defined for combinations of C-strings and chars. For all C-strings you would have to use strcat repeatedly.

The addition operator is defined if at least one of the operands is a std::string, so you could, for example, write
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
using namespace std;

int main()
{
  char gigs = 'C';

  string str = "java =Xmx";
  str = str + gigs + "G -Xms" + gigs + "G";

  cout << "Result is " << str << '\n';
}



An alternative, which might be better if gigs was, for example, numeric like an int or double rather than a char, would be to build up the command in a stringstream before assigning to a string:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
  char gigs = 'C';

  stringstream ss;
  ss << "java =Xmx" << gigs << "G -Xms" << gigs << "G";
  string str = ss.str();

  cout << "Result is " << str << '\n';
}
Hi,

If the strings you wanted to print were in a vector, and gigs was a string literal, then one could use this example here, substitute whatever gigs is instead of "\n" :

https://stackoverflow.com/questions/3008094/c-vector-to-stringstream

I have a vague memory of there being an easier way, conceptually like if stringstreams operator<< would take another string or char argument which is the delimiter, but it would work for different types. I found this experimental code:

http://en.cppreference.com/w/cpp/experimental/ostream_joiner
sprintf is the clean way to do a lot of stuff with C strings. Actually it can behave as if strcat, strcpy, and xtoa family conversions, to name a few of its many powers. It is almost-WYSIWYG which can be nice as well (I miss that the most using the newer stuff).

char result[1000]; //whatever
sprintf(result, "%s static text and an integer variable %i another string %s %s", string1, integer1, string2, string3);



If you're using one of the recent versions of the C++ standard you can use C++ string literals instead.

1
2
  // Using C++ string literals instead of const char literals (note the 's' after the literals).
  string str = "java =Xmx"s + gigs + "G -Xms"s + gigs + "G"s; 


Also you will need to use the c_str() member function in that call to system().

Last edited on
Here is some template code to handle delimiters with different types, also begin and end tags:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <string>


const std::string DelimiterArg = ",";

// Base case for template recursion, print with delimiters only
template <typename T>
void PrintDelimiters(std::string DelimiterArg, T arg) {
	DelimiterArg = "";
	std::cout << arg << "\n";
}

template <typename T,  typename... Types>

void PrintDelimiters (std::string Delimiter, T FirstArg, Types... args) {
	std::cout << FirstArg << Delimiter << " ";
	PrintDelimiters( DelimiterArg, args...);
}

// Base case for template recursion, print with delimiters and begin / end tags
template <typename T>
void PrintDelimiters(std::string DelimiterArg,
		std::string BeginTag,
		std::string EndTag,
		T arg)
{
	DelimiterArg = "";
	std::cout << BeginTag << arg << EndTag << "\n";
}

template <typename T,  typename... Types>
void PrintDelimiters (std::string Delimiter,
		std::string BeginTag,
		std::string EndTag,
		T FirstArg, Types... args
		)
{
	std::cout << BeginTag <<  FirstArg << EndTag << Delimiter << " ";
	PrintDelimiters( DelimiterArg, BeginTag, EndTag, args...);
}

int main() {

	//auto Fred = std::make_tuple("Fed Dagg", 2.0, 47);

	PrintDelimiters(DelimiterArg, "Fred", "Dag", 2.0, 47);

	const std::string BeginTag = "[ code]";
	const std::string EndTag = "[/ code]";

	PrintDelimiters(DelimiterArg, BeginTag, EndTag, "Fred", "Dag", 2.0, 47);

	return 0;
}



Fred, Dag, 2, 47
[code]Fred[/code], [code]Dag[/code], [code]2[/code], [code]47[/code]


Edit:

I put spaces in the code tags, so it didn't mess up the code tags here :+) The output is from my IDE.
Last edited on
I example I quoted above, where a container has a number of homogeneous items, could be used to write that data to a CSV file.

Now I just need to write some more template code to take a std::tuple as an argument. Then we can have a class which has a function that returns a std::tuple containing it's data member values. We can use that to serialise those objects to a variety of file formats (CSV, space delimited, tab delimited, XML)
Topic archived. No new replies allowed.