l have a string like "hello_1_world". And in each iteration l want to increment "1" part. "hello_2_world", "hello_3_world" etc... So l can not use const char*
or string_view
. l have to allocate new memory in every iteration by using std::string
. But, l do not want to because of performance issue. Could you suggest a solution?
So, my code is like below. Guess index is incrementing each time.
std::string value{"hello_" std::to_string(index) "_world"};
l tried so many ways. And one of them is like below:
string_view result(value, 39);
And concat something but again. l cant modify string_view
CodePudding user response:
Do you really need a std::string
, or will a simple char[]
suffice? If so, then try something like this:
// a 32bit positive int takes up 10 digits max...
const int MAX_DIGITS = 10;
char value[6 MAX_DIGITS 6 1];
for(int index = 0; index < ...; index) {
std::snprintf(value, std::size(value), "hello_%d_world", index);
// use value as needed...
}
Alternatively, if you don't mind having leading zeros in the number, then you can update just that portion of the buffer on each iteration:
const int MAX_DIGITS = ...; // whatever you need, up to 10 max
char value[6 MAX_DIGITS 6 1];
std::strcpy(value, "hello_");
std::strcpy(&value[6 MAX_DIGITS], "_world");
for(int index = 0; index < ...; index) {
std::snprintf(&value[6], MAX_DIGITS, "%0.*d", MAX_DIGITS, index);
// use value as needed...
}
If you really need a std::string
, then simply pre-allocate it before the iteration, and then fill in its existing memory during the iteration, similar to a char[]
:
const int MAX_DIGITS = 10;
std::string value;
value.reserve(6 MAX_DIGITS 6); // allocate capacity
for(int index = 0; index < ...; index) {
value.resize(value.capacity()); // preset size, no allocation when newsize <= capacity
std::copy_n("hello_", 6, value.begin());
auto ptr = std::to_chars(&value[6], &value[6 MAX_DIGITS], index).ptr;
/* or:
auto numWritten = std::snprintf(&value[6], MAX_DIGITS, "%d", index);
auto ptr = &value[6 numWritten];
*/
auto newEnd = std::copy_n("_world", 6, ptr);
value.resize(newEnd - value.data()); // no allocation when shrinking size
// use value as needed...
}
Alternatively, with leading zeros:
const int MAX_DIGITS = ...; // up to 10 max
std::string value(6 MAX_DIGITS 6, '\0');
std::copy_n("hello_", 6, value.begin());
std::copy_n("_world", 6, &value[6 MAX_DIGITS]);
for(int index = 0; index < ...; index) {
std::snprintf(&value[6], MAX_DIGITS, "%0.*d", MAX_DIGITS, index);
// use value as needed...
}
CodePudding user response:
you could use a std::stringstream
to construct the string incrementally:
std::stringstream ss;
ss << "hello_";
ss << index;
ss << "_world";
std::string value = ss.str();