Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(How) can I use the Boost String Algorithms Library with c strings (char pointers)?

Is it possible to somehow adapt a c-style string/buffer (char* or wchar_t*) to work with the Boost String Algorithms Library?

That is, for example, it's trimalgorithm has the following declaration:

template<typename SequenceT> 
void trim(SequenceT &, const std::locale & = std::locale());

and the implementation (look for trim_left_if) requires that the sequence type has a member function erase.

How could I use that with a raw character pointer / c string buffer?

char* pStr = getSomeCString(); // example, could also be something like wchar_t buf[256];
...
boost::trim(pStr); // HOW?

Ideally, the algorithms would work directly on the supplied buffer. (As far as possible. it obviously can't work if an algorithm needs to allocate additional space in the "string".)


@Vitaly asks: why can't you create a std::string from char buffer and then use it in algorithms?

The reason I have char* at all is that I'd like to use a few algorthims on our existing codebase. Refactoring all the char buffers to string would be more work than it's worth, and when changing or adapting something it would be nice to just be able to apply a given algorithm to any c-style string that happens to live in the current code.

Using a string would mean to (a) copy char* to string, (b) apply algorithm to string and (c) copy string back into char buffer.

like image 620
Martin Ba Avatar asked Nov 04 '11 10:11

Martin Ba


2 Answers

For the SequenceT-type operations, you probably have to use std::string. If you wanted to implement that by yourself, you'd have to fulfill many more requirements for creation, destruction, value semantics etc. You'd basically end up with your implementation of std::string.

The RangeT-type operations might be, however, usable on char*s using the iterator_range from Boost.Range library. I didn't try it, though.

like image 171
jpalecek Avatar answered Sep 28 '22 07:09

jpalecek


There exist some code which implements a std::string like string with a fixed buffer. With some tinkering you can modify this code to create a string type which uses an external buffer:

char buffer[100];
strcpy(buffer, "   HELLO   ");

xstr::xstring<xstr::fixed_char_buf<char> >
    str(buffer, strlen(buffer), sizeof(buffer));

boost::algorithm::trim(str);
buffer[str.size()] = 0;

std::cout << buffer << std::endl;   // prints "HELLO"

For this I added an constructor to xstr::xstring and xstr::fixed_char_buf to take the buffer, the size of the buffer which is in use and the maximum size of the buffer. Further I replaced the SIZE template argument with a member variable and changed the internal char array into a char pointer.

The xstr code is a bit old and will not compile without trouble on newer compilers but it needs some minor changes. Further I only added the things needed in this case. If you want to use this for real, you need to make some more changes to make sure it can not use uninitialized memory.

Anyway, it might be a good start for writing you own string adapter.

like image 43
rve Avatar answered Sep 28 '22 06:09

rve