(Как) я могу использовать библиотеку Boost String Algorithms со строками c (указатели на символы)? - PullRequest
7 голосов
/ 04 ноября 2011

Можно ли каким-то образом адаптировать строку / буфер в стиле c (char* или wchar_t*) для работы с библиотекой алгоритмов ускорения строк ?

То есть, например, алгоритм trim имеет следующее объявление:

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

и реализация (ищите trim_left_if) требует, чтобы тип последовательности имел функцию-член erase.

Как я могу использовать это с необработанным символьным указателем / строковым буфером c?

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

В идеале алгоритмы должны работать непосредственно с предоставленным буфером. (Насколько это возможно. Очевидно, что он не может работать, если алгоритму нужно выделить дополнительное пространство в «строке».)


@ Виталий спрашивает: почему вы не можете создать std :: string из буфера символов и затем использовать ее в алгоритмах?

Причина, по которой у меня вообще есть char *, заключается в том, что я хотел бы использовать несколько algorthims в нашей существующей кодовой базе. Рефакторинг всех буферов символов в строку будет более трудоемким, чем оно того стоит, и при изменении или адаптации чего-либо было бы просто иметь возможность применить данный алгоритм к любой строке в стиле c, которая, как оказалось, живет в текущем коде.

Использование строки означало бы (a) копировать char * в строку, (b) применить алгоритм к строке и (c) скопировать строку обратно в буфер символов.

Ответы [ 3 ]

5 голосов
/ 04 ноября 2011

Для операций типа SequenceT вам, вероятно, придется использовать std::string.Если бы вы захотели реализовать это самостоятельно, вам бы пришлось выполнить гораздо больше требований по созданию, уничтожению, семантике значений и т. Д. В итоге вы бы получили реализацию std::string.

* * 1006.Однако операции * -типа можно использовать на char* с использованием iterator_range из библиотеки Boost.Range.Впрочем, я этого не пробовал.

1 голос
/ 07 ноября 2011

Существует некоторый код , который реализует std::string подобную строку с фиксированным буфером.Немного повозившись, вы можете изменить этот код для создания строкового типа, который использует внешний буфер:

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"

Для этого я добавил конструктор в xstr::xstring и xstr::fixed_char_buf, чтобы взять буфер, размериспользуемый буфер и максимальный размер буфера.Далее я заменил аргумент шаблона SIZE на переменную-член и изменил внутренний массив char на указатель char.

Код xstr немного устарел и не будет компилироваться без проблем на новых компиляторах, но он требует некоторых небольших изменений.Далее я добавил только то, что нужно в этом случае.Если вы хотите использовать это по-настоящему, вам нужно внести еще некоторые изменения, чтобы убедиться, что он не может использовать неинициализированную память.

В любом случае, это может быть хорошим началом для написания собственного строкового адаптера.

0 голосов
/ 04 ноября 2011

Я не знаю, на какую платформу вы нацеливаетесь, но на большинстве современных компьютеров (включая мобильные, например, ARM) копирование памяти происходит так быстро, что вам даже не нужно тратить время на оптимизацию копий памяти. Я говорю - заверните char* в std::string и проверьте, соответствует ли производительность вашим потребностям. Не тратьте время на преждевременную оптимизацию.

...