This buffer should contain slots (three in this example) of equal length ( 20 in this example)
The buffer has to have contiguous memory so that it can be passed to a C function in non-const fashion.
const int slot_size = 20;
std::vector<char> vbuffer;
This function takes a string, copies to a temporary buffer of the required size then appeds it to vbuffer
void prepBuffer( const std::string& s)
{
std::vector<char> temp(slot_size);
std::copy(s.c_str(), s.c_str() + s.length() + 1, temp.begin());
vbuffer.insert(vbuffer.end(), temp.begin(), temp.end());
}
Testing the function
int main()
{
vbuffer.reserve(60);
prepBuffer( "Argentina");
prepBuffer( "Herzegovina");
prepBuffer( "Zambia");
cout << &vbuffer[0] << endl;
cout << &vbuffer[20] << endl;
cout << &vbuffer[40] << endl;
}
Question. There is a lot of string copying in my prepBuffer
function. I am looking for a better way to fill up vbuffer
with minimal copying
EDIT
The size of slots is determined elsewhere in the program. But it is not known at compile time.
EDIT
In line with my accepted answer below, I have settled on this version
void prepBuffer(const std::string& s)
{
assert(s.size() < slot_size );
vbuffer.insert(vbuffer.end(), s.begin(), s.end());
vbuffer.insert(vbuffer.end(), slot_size - s.size(), '\0' );
}
Suggestions are still welcome
How about this:
vbuffer.reserve(vbuffer.size() + 20);
vbuffer.insert(vbuffer.end(), s.begin(), s.end());
vbuffer.insert(vbuffer.end(), 20 - s.size(), '\0');
An additional check on the string length is recommended, along with a policy for handling over-long strings (e.g. assert(s.size() < 20);
).
If you don't use std::string
at all and avoid the temporary std::vector
, you can easily do this without any extra dynamic allocation.
template <unsigned N>
void prepBuffer(char const (&s)[N])
{
std::copy(s, s + N, std::back_inserter(vbuffer));
vbuffer.resize(vbuffer.size() - N + 20);
}
Or, since the number of characters to be written is known ahead of time, you could just as easily use a nontemplate function:
void prepBuffer(char const* s)
{
unsigned n = vbuffer.size();
vbuffer.resize(n + 20);
while (*s && n != vbuffer.size())
{
vbuffer[n] = *s;
++n;
++s;
}
assert(*s == 0 && n != vbuffer.size());
// Alternatively, throw an exception or handle the error some other way
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With