Зачем использовать строки c в C++?

есть ли веская причина использовать C-строки в C++ в настоящее время? В некоторых случаях мой учебник использует их в примерах, и я действительно чувствую, что было бы проще просто использовать std::string.

18 ответов


единственные причины, по которым я должен был использовать их, - это взаимодействие с сторонними библиотеками, которые используют строки стиля C. Также могут быть эзотерические ситуации, когда вы будете использовать строки стиля C по соображениям производительности, но чаще всего использование методов на строках c++, вероятно, быстрее из-за вставки и специализации и т. д.

можно использовать c_str() метод во многих случаях при работе с такого рода API, но вы должны знать, что char * возвращается const, и вы не должны изменять строку с помощью этого указателя. В таких ситуациях вы все равно можете использовать вектор и, по крайней мере, получить преимущество более легкого управления памятью.


еще несколько заметок управления памятью:

строки C являются типами POD, поэтому они могут быть выделены в сегменте данных только для чтения вашего приложения. Если вы объявите и определите std::string константы в области пространства имен компилятор будет генерировать дополнительный код, который выполняется до main() что называет std::string конструктор для каждой константы. Если ваше приложение имеет много постоянных строк (например, если вы создали код C++, который использует постоянные строки), строки C могут быть предпочтительными в этом ситуация.

некоторые реализации std::string поддержка функции SSO ("оптимизация коротких строк "или" оптимизация небольших строк"), где std::string класс содержит хранилище для строк до определенной длины. Это увеличивает размер std::string но часто значительно уменьшает частоту распределений/освобождений свободного магазина, улучшая представление. Если ваша реализация std::string не поддерживает SSO, а затем создает пустой std::string на стек выполните выделение свободного хранилища. Если это так, использование временных строк C, выделенных стеком, может быть полезно для кода с критической производительностью, который использует строки. Конечно, вы должны быть осторожны, чтобы не выстрелить себе в ногу, когда вы это делаете.


потому что так они поступают из многочисленных API/библиотек?


предположим, у вас есть некоторые строковые константы в коде, что является довольно распространенной необходимостью. Лучше определить их как строки C, чем как объекты c++ - более легкие, портативные и т. д. Теперь, если вы собираетесь передавать эти строки различным функциям, хорошо, если эти функции принимают строку C вместо того, чтобы требовать строковый объект c++.

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


Контроль памяти. Недавно мне пришлось обрабатывать строки (фактически blobs из базы данных) размером около 200-300 МБ в массовом многопоточном приложении. Это была ситуация, когда еще одна копия строки могла бы разорвать 32-битное адресное пространство. Я должен был точно знать, сколько копий этой строки существует. Хотя я евангелист STL, я использовал char * тогда, потому что это дало мне гарантию, что никакая дополнительная память или даже дополнительная копия не была выделена. Я точно знал, сколько там места. необходимость.

кроме того, стандартная обработка строк STL пропускает некоторые большие функции C для обработки/синтаксического анализа строк. К счастью, std:: string имеет метод c_str() для доступа const к внутреннему буферу. Чтобы использовать printf (), вам все равно придется использовать char * хотя (какая сумасшедшая идея команды C++ не включать (ы) printf-подобные функции, одна из самых полезных функций когда-либо в C. Я надеюсь, что boost::format скоро будет включен в STL.


Если функция нуждается в постоянный string я по-прежнему предпочитаю использовать 'const char*' (или const wchar_t*), даже если программа использует std::string, CString, EString или что-то еще.

в большой базе кода слишком много источников строк, чтобы быть уверенным, что вызывающий будет иметь строку как std:: string и 'const char*' является наименьшим общим знаменателем.


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


Если код c++ "глубокий" (близко к ядру, сильно зависит от библиотек C и т. д.) вы можете явно использовать строки C, чтобы избежать множества преобразований в и из std:: string. Of, если вы взаимодействуете с другими языковыми доменами (Python,Ruby и т. д.) вы можете сделать это по той же причине. В противном случае используйте std::string.


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

в моем случае я пытался получить около 1 ГБ строк из файла 2 ГБ, поместить их в записи с примерно 60 полями, а затем отсортировать их 7 раз по-разному поля. Мой код предшественников занял 25 часов с char*, мой код работал в 1 час.


потратив слишком много времени на отладку правил инициализации и каждой возможной реализации строк на нескольких платформах, Мы требуем, чтобы статические строки были const char*.

потратив слишком много времени на отладку плохого кода char* и утечек памяти, я предлагаю, чтобы все нестатические строки были каким-то типом строкового объекта ... пока профилирование не покажет, что вы можете и должны сделать что-то лучше; -)


учитывая выбор, обычно нет причин выбирать примитивные строки C (char*) по c++ строки (std::string). Однако часто у вас нет такой роскоши, как выбор. Например, std::fstreamконструкторы берут строки C по историческим причинам. Кроме того, библиотеки C (вы догадались!) использовать C-строками.

в вашем собственном коде C++ лучше всего использовать std::string и извлеките строку c объекта по мере необходимости, используя c_str() функции std::string.


Это зависит от библиотек, которые вы используете. Например, при работе с MFC, часто проще использовать CString при работе с различными частями API Windows. Он также, кажется, работает лучше, чем std:: string в приложениях Win32.

однако std:: string является частью стандарта C++, поэтому, если вы хотите улучшить переносимость, перейдите к std::string.


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


строки c не несут накладных расходов на то, чтобы быть классом.

строки c обычно могут привести к более быстрому коду, так как они ближе к машинному уровню

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

существует множество вызовов libary, которые требуют их по историческим причинам.

научитесь использовать строки c и STL и использовать их, когда это имеет смысл.


1)" string constant " -это строка C (const char*), преобразующая ее в const std::string& - это процесс времени выполнения, не обязательно простой или оптимизированный. 2) библиотека fstream использует строки c-стиля для передачи имен файлов.

мое эмпирическое правило-передать const std::string&, если я собираюсь использовать данные как std:: string в любом случае (скажем, когда я храню их в векторе), и const char * в других случаях.


устаревший код, который не знает std::string. Кроме того, до C++11 открытие файлов с помощью std::ifstream или std::ofstream было возможно только с помощью const char* в качестве ввода имени файла.


строки STL, безусловно, намного проще в использовании, и я не вижу причин не использовать их.

Если вам нужно взаимодействовать с библиотекой, которая принимает только строки c-стиля в качестве аргументов, вы всегда можете вызвать метод c_str () класса string.


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