преобразование char [] (c lang) в строку (c ++ lang) - PullRequest
2 голосов
/ 08 августа 2009

Я вижу, что почти все современные API разработаны на языке Си. Для этого есть причины: скорость обработки, низкий уровень языка, кроссплатформенность и т. Д.

В настоящее время я программирую на C ++ из-за его объектной ориентации, использования строки, STL, но главным образом потому, что это лучший C.

Однако, когда моим программам на C ++ необходимо взаимодействовать с API-интерфейсами C, я действительно расстраиваюсь, когда мне нужно преобразовать типы char [] в строки C ++, затем работать с этими строками, используя мощные методы, и, наконец, преобразовать эти строки в char [ ] (потому что API должен получать символ []).

Если я повторяю эти операции для миллионов записей, время обработки увеличивается из-за задачи преобразования. По этой простой причине я чувствую, что char [] в настоящее время является препятствием для принятия C ++ как лучшего c.

Я хотел бы знать, чувствуете ли вы то же самое, если нет (я надеюсь, что так!), То я действительно хотел бы знать, какой лучший способ для C ++ сосуществовать с типами char [] без выполнения этих ужасных преобразований. Спасибо за ваше внимание.

Ответы [ 6 ]

4 голосов
/ 08 августа 2009

Строковый класс C ++ имеет много проблем, и да, то, что вы описываете, является одной из них.

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

И поскольку практически все алгоритмы обработки строк реализованы как члены класса, они могут только использоваться в классе строк.

Решением, с которым вы можете поэкспериментировать, является комбинация Boost.Range и Boost.StringAlgo.

Диапазон позволяет создавать последовательности из пары итераторов. Они не берут на себя ответственность за данные, поэтому не копируют строку. они просто указывают на начало и конец вашей строки * char.

И Boost.StringAlgo реализует все общие строковые операции как функции, не являющиеся членами, которые могут применяться к любой последовательности символов. Таких как, например, Boost range.

Комбинация этих двух библиотек в значительной степени решает проблему. Они позволяют вам избежать копирования ваших строк для их обработки.

Другим решением может быть сохранение ваших строковых данных как std::string все время . Когда вам нужно передать char* какой-либо функции API, просто передайте ей адрес первого символа. (& Ул [0]).

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

3 голосов
/ 08 августа 2009

Если вы используете std::vector<char> вместо std::string, базовым хранилищем будет массив C, к которому можно получить доступ с помощью &someVec[0]. Тем не менее, вы теряете много std::string удобств, таких как operator+.

Тем не менее, я бы предложил просто избегать C API, которые изменяют строки в максимально возможной степени. Если вам нужно передать неизменную строку в функцию C, вы можете использовать c_str(), что является быстрым и не копирует в большинстве реализаций std::string.

1 голос
/ 08 августа 2009

Я не уверен, что вы подразумеваете под "преобразованием", но не достаточно ли следующего для перемещения между char*, char[] и std::string?

char[] charString = {'a', 'b', 'c', '\0'};
std::string standardString(&charString[0]);
const char* stringPointer(standardString.c_str());
0 голосов
/ 08 августа 2009

"... потому что это лучший C".

Чушь. C ++ - значительно худший диалект языка C. Решаемые им проблемы тривиальны, проблемы, которые он приносит, гораздо хуже, чем те, которые он решает.

0 голосов
/ 08 августа 2009

Я не уверен, почему вы были бы ограничены использованием строк C и все еще имеете среду, которая выполняет код C ++, но если вы действительно не хотите накладных расходов на преобразование, чем не преобразовывать. Просто напишите подпрограммы, которые работают со строками C.

Другая причина для преобразования в строки стиля C ++ связана с безопасностью.

0 голосов
/ 08 августа 2009

Я не думаю, что это так плохо, как ты думаешь.

Существует стоимость преобразования char [] в std :: string, но если вы собираетесь модифицировать строку, вам все равно придется оплатить эту стоимость, будь то преобразование в std :: string или копирование в другое буфер char [].

Преобразование, идущее другим путем (через string.c_str ()), обычно тривиально. Обычно он возвращает указатель на внутренний буфер (просто не передавайте этот буфер коду, который его изменит).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...