Подтвердить что ты не робот

Разница между string.h и cstring?

В чем разница между string.h и cstring?

Какой из них следует использовать для C и какой для С++ (если вообще)?

4b9b3361

Ответ 1

В С++ вы должны включить 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, я думаю, либо он может быть использован в С++, если он используется надлежащим образом.

Ответ 2

В С++ заголовки языка C определяются в пространстве имен std. Итак, если вы используете эти заголовки на С++, используйте cstring и устраните .h.

Ответ 3

Вы можете использовать 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

Ответ 4

Существует тонкая разница между string.h и cstring

Ответа на этот вопрос Alf P. Steinbach (можно найти в комментариях к заданному вопросу):

string.h помещает идентификаторы в глобальное пространство имен и может также помещать их в стандартное пространство имен. Пока cstring помещает идентификаторы в стандартное пространство имен и может также помещать их в глобальное пространство имен. Вы определенно не хотите этого поведения cstring, потому что код, например, использует только strlen, может отлично работать с одним компилятором, а затем не скомпилировать с другим компилятором. Это очень неприятный сюрприз. Для C и С++ используйте более безопасный string.h.

Ответ 5

Версия заголовка С++ на самом деле имеет некоторые отличия от версии 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 для этих типов.

Ответ 6

По-видимому cstring для С++ и string.h для C.

Следует упомянуть о том, что если вы переключаетесь с string.h на cstring, не забудьте добавить std:: перед тем, как вызовет все ваши строковые функции.