views:

264

answers:

3

Simple question: If I have a string and I want to add to it head and tail strings (one in the beginning and the other at the end), what would be the best way to do it? Something like this:

std::string tmpstr("some string here");
std::string head("head");
std::string tail("tail");
tmpstr = head + tmpstr + tail;

Is there any better way to do it?

Thanks in advance.

A: 

You could append the tail and then cocatenate the string, like this:

tmpstr.append(tail);
tmpstr = head + tmpstr;

It would probably be better to just create a new string at that point.

std::string finalstr(head.length() + tmpstr.length() + 1);
finalstr = head + tmpstr;
Hooked
Um, that `std::string` ctor taking a `std::string::size_type` does this really reserve??? (Yeah, I know I could look it up. Sorry for being lazy.)
sbi
OK, so I looked it up this morning and found that there is no ctor taking only a `std::string::size_type`, so the code is wrong. (You'*d have to call `reserve()` after using the dctor.)
sbi
There is a constructor that takes (size_t, char) which you can use. I omitted the comma and the '\0' because I assumed you understood. length() returns the length of the string, not a special type.
Hooked
std::string finalstr(head.length() + tmpstr.length() + 1, '\0'); Also, don't downvote me if you do not understand what you are talking about.
Hooked
@Hooked: Even if we allow for you omitting the second parameter, the ctor taking a `std::string::size_type` and a `char` affects the string's size (changed in the very next line), not its capacity. I downvoted, not you, but your answer -- and I did so _after_ I checked the facts, BTW -- because the answer's code doesn't compile. The code in your comment would compile, but, as I said, would be wrong.
sbi
+19  A: 

If you were concerned about efficiency and wanted to avoid the temporary copies made by the + operator, then you could do:

tmpstr.insert(0, head);
tmpstr.append(tail);

And if you were even more concerned about efficiency, you might add

tmpstr.reserve(head.size() + tmpstr.size() + tail.size());

before doing the inserting/appending to ensure any reallocation only happens once.

However, your original code is simple and easy to read. Sometimes that's "better" than a more efficient but harder to read solution.

TheUndeadFish
+1 for easier to read. That's what really counts.
Greg Hewgill
great answer! thanks!Thanks also for discussing both issues or readability and efficiency.
Andrew
checked with profiler. depends on compilator but in my case this approach is far more efficient.
Andrew
+1  A: 

An altogether different approach:

#include <iostream>
#include <string>
#include <sstream>

int
main()
{
  std::string tmpstr("some string here");
  std::ostringstream out;
  out << head << tmpstr << tail;
  tmpstr = out.str(); // "headsome string heretail"

  return 0;
}

An advantage of this approach is that you can mix any type for which operator<< is overloaded and place them into a string.

  std::string tmpstr("some string here");
  std::ostringstream out;
  int head = tmpstr.length();
  char sep = ',';
  out << head << sep << tmpstr;
  tmpstr = out.str(); // "16,some string here"
Vijay Mathew