2009-08-07 3 views
2

Я вижу, что почти все современные API-интерфейсы разработаны на языке C. Есть причины для этого: скорость обработки, язык низкого уровня, кросс-платформа и так далее.char [] (c lang) to string (C++ lang) conversion

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

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

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

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

+4

пунктуация, разрывы строк. Научитесь их использовать. Это делает ваш вопрос намного легче читать. ;) – jalf

+0

Выглядит хорошо jalf :) – GManNickG

+1

Прошу прощения, и большое спасибо за ваши полезные исправления. – 2009-08-08 02:11:39

ответ

4

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

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

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

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

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

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

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

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

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

+0

Что касается последнего абзаца, вызов str.c_str() гарантирует, что строка nul завершена и возвращает указатель const на строку. –

+1

Также, принимая адрес буфера, это плохая, плохая, плохая идея. Библиотека вообще не дает никаких гарантий относительно буфера .. c_str() - правильный подход. Однако помните, что c_str() работает только до тех пор, пока вы не оставите строковый объект самостоятельно, в то время как кто-то может использовать буфер, на который указывает c_str(). Если вы вызываете какие-либо строковые методы, все ставки отключены. – Christopher

+0

Не является ли стандартная гарантия непрерывности буфера? Или это только гарантировано в C++ 0x? – jalf

1

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

char[] charString = {'a', 'b', 'c', '\0'}; 
std::string standardString(&charString[0]); 
const char* stringPointer(standardString.c_str()); 
+1

Любая конкретная причина для 'std :: string standardString (& charString [0])', а не просто 'std :: string standardString (charString)'? –

+0

Не совсем. По какой-то причине я думал, что компилятор предупредит, что char [] не конвертируется в char *, что в ретроспективе глупо. –

3

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

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

+1

Следует отметить, что на практике нет известной реализации C++, в которой std :: string не будет использовать непрерывное хранилище для строковых данных. Из-за этого C++ 0x явно потребует, чтобы в стандарте, и в целом, можно было бы предположить, что это будет выполняться для всех существующих и новых реализаций. –

+1

Однако std :: string все еще не предлагает способ для указания указателя _mutable_ на его базовые данные, afaik – bdonlan

+0

Используя std: vector, базовое хранилище будет * вероятно * быть массивом, но в спецификации нет гарантии что это будет. – Christopher

0

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

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

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

+0

Я забыл упомянуть, что я также взаимодействую с библиотеками C++, и это еще одна причина для преобразования, я читаю строки c, преобразую строку C++, чтобы вызывать внешние функции C++. И я очень плохо вижу, что большинство моих кодов C++ содержат эти преобразования. Кто-то сказал мне, эй! забудьте C++ и сделайте это в c !! – 2009-08-08 01:49:02

0

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

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

+0

За исключением строк C++ гораздо проще манипулировать ...? – GManNickG

+0

@GMan Спасибо, что указали это. Главным моментом, который я пытался понять в этом втором абзаце, является то, что плакат не рассматривал безопасность, которая является большой IMHO – Steve

-5

«... потому что это лучше C.».

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

+0

... как это особенно заметно, когда она имеет проблемное взаимодействие с C API, который использует 40 летней технологии, чтобы передавать струны туда и сюда? Извините, но это глупо. – sbi

Смежные вопросы