В чем разница между string.h
и cstring
?
Какой из них следует использовать для C и какой для С++ (если вообще)?
В чем разница между string.h
и cstring
?
Какой из них следует использовать для C и какой для С++ (если вообще)?
В С++ вы должны включить cstring
в качестве заголовка, а в c вы должны включить string.h
в качестве заголовка.
В С++
#include <cstring>
В C
#include <string.h>
Особенности стандартной библиотеки C также предоставляются в стандартной библиотеке С++ и в качестве общего соглашения об именах они предварительно привязаны c
к соответствующим именам в стандартной библиотеке C.
Например: string.h
становится cstring
stdio.h
становится cstdio
и т.д.
Поскольку другие ответы добавили разные измерения в это обсуждение, я чувствовал себя вынужденным ссылаться на священный стандарт, чтобы очистить этот бит.
В соответствии с С++ 11 20.9.14.6 и 7:
Таблица 55 описывает заголовок
<cstring>
.
Содержимое совпадает с заголовком библиотеки Standard C с изменением наmemchr()
, указанным в 21.7.
Хотя 21.7 Утилит последовательности с нулевым завершением:
Подпись функции
memchr(const void*, int, size_t)
должна быть заменена двумя объявлениями:const void* memchr(const void* s, int c, size_t n); void* memchr( void* s, int c, size_t n);
оба из них должны иметь такое же поведение, что и оригинальное объявление.
Приложение D (нормативное) Особенности совместимости [des]:
D.6 C стандартные заголовки библиотек
1 Для совместимости со стандартной библиотекой C и C Unicode TR стандартная библиотека С++ предоставляет заголовки 25 C, как показано в таблице 151.
К ним относятся:
<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h>
<complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h>
<ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h>
<errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h>
<fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>
Далее,
2 Каждый заголовок C, каждый из которых имеет имя формы
name.h
, ведет себя так, как будто каждое имя, помещенное в пространство имен стандартной библиотеки соответствующимcname header
, помещается в область глобального пространства имен. Неизвестно, будут ли эти имена сначала объявлены или определены в области пространства имен (3.3.6) пространства имен std и затем будут введены в область глобального пространства имен явным использованием-деклараций (7.3.3).3 [Пример: заголовок
<cstdlib>
, несомненно, предоставляет свои объявления и определения в пространстве имен std. Он также может предоставлять эти имена в глобальном пространстве имен. Заголовок<stdlib.h>
, несомненно, предоставляет те же декларации и определения в глобальном пространстве имен, как и в стандарте C. Он также может содержать эти имена в пространстве имен std. -end пример]
Из приведенных выше ссылок:
Я согласен с моим предыдущим предложением, кажется, нет явного преимущества использования cstring
над string.h
, а поскольку @Alf предположил, что могут возникнуть некоторые проблемы компиляции из-за использования неквалифицированных имен функций при использовании cstring
в качестве заголовка. Таким образом, в данной шляпе нет очевидного преимущества использования string.h
или преимущества использования cstring
, я думаю, либо он может быть использован в С++, если он используется надлежащим образом.
В С++ заголовки языка C определяются в пространстве имен std. Итак, если вы используете эти заголовки на С++, используйте cstring и устраните .h.
Вы можете использовать string.h для C и С++.
В спецификации С++ 98 он определяет как cstring (в основной спецификации), так и string.h(в приложении D.5, заголовки библиотеки стандартного C для совместимости), которые определяют некоторую строковую функцию так же, как string.h в C. И в реальном мире весь компилятор С++ предоставит string.h для совместимости с C-кодом.
Итак, на мой взгляд, поскольку С++-код может поддерживаться C-кодером и привычкой с C, я предпочитаю string.h. Он достаточно прост, широко известен и более совместим (с C).
Кстати, я перечисляю все 18 заголовков на С++ для совместимости с C в спецификации С++ 98: assert.h, iso646.h, setjmp.h, stdio.h, wchar.h, ctype.h, limits.h, signal.h, stdlib.h, wctype.h, errno.h, locale.h, stdarg. h, string.h, float.h, math.h, stddef.h, time.h
Существует тонкая разница между string.h и cstring
Ответа на этот вопрос Alf P. Steinbach (можно найти в комментариях к заданному вопросу):
string.h
помещает идентификаторы в глобальное пространство имен и может также помещать их в стандартное пространство имен. Пока cstring
помещает идентификаторы в стандартное пространство имен и может также помещать их в глобальное пространство имен. Вы определенно не хотите этого поведения cstring
, потому что код, например, использует только strlen
, может отлично работать с одним компилятором, а затем не скомпилировать с другим компилятором. Это очень неприятный сюрприз. Для C и С++ используйте более безопасный string.h
.
Версия заголовка С++ на самом деле имеет некоторые отличия от версии C. В C некоторые типы реализуются как typedefs, но для С++, которые препятствуют тому, что специализация шаблонов работает над этими типами *, поэтому С++ делает некоторые C typedefs в реальных типах. Это означает, что С++ версия заголовков C, содержащих эти typedefs, должна их пропускать.
С++ также допускает перегрузку, поэтому версия С++ <cstring>
указывает некоторые перегрузки на C-функции, чтобы позволить функции возвращать указатель на неконстантные данные, если входной аргумент является указателем на неконстантные данные, тогда как C принимает и возвращает только указатели на const.
Также я думаю, но не могу найти бит в стандарте, чтобы проверить это прямо сейчас, что версии заголовков С++ должны помещать свои имена в пространство имен std и помещать их только в глобальное пространство имен в качестве дополнительного расширения.
* Например, следующий код:
typedef int Foo;
template<typename T> struct Bar {};
template<> struct Bar<int> {};
template<> struct Bar<Foo> {};
приводит к следующей ошибке:
main.cpp:7:19: error: redefinition of 'Bar<int>'
template<> struct Bar<Foo> {};
^~~~~~~~
main.cpp:5:19: note: previous definition is here
template<> struct Bar<int> {};
^
1 error generated.
В C wchar_t есть typedef, поэтому это помешает специализации, которая применяется к wchar_t, но не к тому, какой тип базового типа используется для wchar_t. Тот факт, что MSVC 2010 реализует char32_t и char16_t как typedefs, не позволяет им предлагать специализации std:: codecvt для этих типов.
По-видимому cstring
для С++ и string.h
для C.
Следует упомянуть о том, что если вы переключаетесь с string.h
на cstring
, не забудьте добавить std::
перед тем, как вызовет все ваши строковые функции.