c++ - una - Diferencia entre string.h y cstring?
string en c++ (6)
Aparentemente cstring
es para C ++ y string.h
es para C.
Una cosa que vale la pena mencionar es que, si está cambiando de string.h
a cstring
, recuerde agregar std::
antes de que todas las funciones de string lo cstring
.
¿Cuál es la diferencia entre string.h
y cstring
?
¿Cuál debería usarse para C y cuál para C ++ (si lo hay)?
En C ++, debe incluir el cstring
como encabezado, mientras que en c debe incluir string.h
como encabezado.
En c ++
#include <cstring>
Cía
#include <string.h>
Las características de la biblioteca estándar de C también se proporcionan en la biblioteca estándar de C ++ y, como convención general de nomenclatura, están precedidas por una c
a los nombres correspondientes en la biblioteca estándar de C.
Por ejemplo:
string.h
convierte en cstring
stdio.h
convierte en cstdio
y así sucesivamente ...
Ya que otras respuestas han agregado diferentes dimensiones a esta discusión, me sentí obligado a referir la norma sagrada para aclarar este bit.
Según C ++ 11 20.9.14.6 y 7 :
La tabla 55 describe el encabezado
<cstring>
.
El contenido es el mismo que el encabezado de la biblioteca C estándar, con el cambio amemchr()
especificado en 21.7.
Mientras que 21.7 estados de utilidad de secuencia terminados en nulo :
La función de firma
memchr(const void*, int, size_t)
se reemplazará por las dos declaraciones:
const void* memchr(const void* s, int c, size_t n); void* memchr( void* s, int c, size_t n);
ambos de los cuales tendrán el mismo comportamiento que la declaración original.
Anexo D (normativo) Características de compatibilidad [depr] estados:
D.6 encabezados de biblioteca estándar
1 Para la compatibilidad con la biblioteca estándar de C y C Unicode TR, la biblioteca estándar de C ++ proporciona los encabezados de 25 C, como se muestra en la Tabla 151.
Que incluye:
<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>
Más allá,
2 Cada encabezado C, cada uno de los cuales tiene un nombre con el nombre nombre del formulario.h, se comporta como si cada nombre colocado en el espacio de nombres de la biblioteca estándar por el
cname header
correspondiente se ubicara dentro del ámbito del espacio de nombres global. No se especifica si estos nombres se declaran o se definen primero dentro del alcance del espacio de nombres (3.3.6) del espacio de nombres estándar y luego se inyectan en el alcance del espacio de nombres global mediante declaraciones de uso explícitas (7.3.3).3 [Ejemplo: el encabezado
<cstdlib>
seguridad proporciona sus declaraciones y definiciones dentro del espacio de nombres std. También puede proporcionar estos nombres dentro del espacio de nombres global. El encabezado<stdlib.h>
seguramente proporciona las mismas declaraciones y definiciones dentro del espacio de nombres global, como en el Estándar C. También puede proporcionar estos nombres dentro del espacio de nombres estándar. —En ejemplo]
Conclusión:
De las referencias anteriores:
Me he corregido de acuerdo con mi sugerencia anterior, no parece haber ninguna ventaja aparente de usar cstring
sobre string.h
mientras que como @Alf sugirió que podría haber algunos problemas de compilación debido al uso de nombres de funciones no calificados cuando se usa cstring
como encabezado. Por lo tanto, dado que no hay una desventaja aparente en el uso de string.h
o la ventaja de usar el uso de cstring
, creo que cualquiera de los dos puede usarse en C ++ si se usa de manera adecuada.
En C ++, los encabezados en lenguaje C se definen bajo el espacio de nombres estándar. Entonces, si estás usando esos encabezados en C ++, usa cstring y elimina .h.
Hay una diferencia sutil entre string.h y cstring
Respuesta de Alf P. Steinbach (se puede encontrar como un comentario a la pregunta):
string.h
coloca los identificadores en el espacio de nombres global, y también puede colocarlos en el espacio de nombres estándar. Mientras que cstring
coloca los identificadores en el espacio de nombres estándar, y también puede colocarlos en el espacio de nombres global. Definitivamente no quieres ese comportamiento de cstring
, porque el código que, por ejemplo, usa solo strlen
puede funcionar bien con un compilador, y luego no compilar con otro compilador. Es una sorpresa muy desagradable. Así que para C y C ++ , use la string.h
más string.h
.
La versión C ++ del encabezado en realidad tiene algunas diferencias con respecto a la versión C. En C, algunos tipos se implementan como typedefs, pero para C ++ eso evita que la especialización de la plantilla funcione en esos tipos *, por lo que C ++ convierte algunos typedefs en C en tipos reales. Esto significa que la versión C ++ de los encabezados de C que contienen esas definiciones de tipo debe omitirlos.
C ++ también permite la sobrecarga, por lo que la versión de C ++ de <cstring>
especifica algunas sobrecargas a las funciones de C para permitir que una función devuelva un puntero a datos no constantes si el argumento de entrada es un puntero a datos no constantes, mientras que la función C y devuelve solo los punteros a const.
También pienso, pero no puedo encontrar el bit en el estándar para verificar esto en este momento, que las versiones C ++ de los encabezados tienen que poner sus nombres en el espacio de nombres estándar y solo colocarlos en el espacio de nombres global como una extensión opcional.
* Por ejemplo el siguiente código:
typedef int Foo;
template<typename T> struct Bar {};
template<> struct Bar<int> {};
template<> struct Bar<Foo> {};
resulta en el siguiente error:
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.
En C, wchar_t es un typedef, por lo que evitaría que uno tenga una especialización que se aplique a wchar_t, pero no a ningún tipo subyacente que se use para wchar_t. El hecho de que MSVC 2010 implemente char32_t y char16_t como typedefs les impide ofrecer las especializaciones std :: codecvt para esos tipos.
Puedes usar string.h tanto para C como para C ++.
En la especificación C ++ 98, define tanto la cadena de caracteres (en la especificación principal) como la cadena.h (en el Anexo D.5, Encabezados de la biblioteca C estándar, para compatibilidad), que definen una función de cadena igual a la cadena.h en C. Y en el mundo real, todo el compilador de C ++ proporcionará string.h para compatibilidad con el código C.
Entonces, en mi opinión, como el código C ++ puede ser mantenido por el codificador C, y el hábito de C, prefiero string.h. Es suficientemente claro, ampliamente conocido y más compatible (con C).
Por cierto, enumero los 18 encabezados en C ++ para compatibilidad con C, en C ++ 98 spec: assert.h, iso646.h, setjmp.h, stdio.h, wchar.h, ctype.h, limits.h, señal. h, stdlib.h, wctype.h, errno.h, locale.h, stdarg.h, string.h, float.h, math.h, stddef.h, time.h