La documentación es correcta. Úselo c_str()
si desea una cadena terminada en nulo.
Si los implementadores lograron implementar data()
en términos de c_str()
usted, no tiene que preocuparse, aún use data()
si no necesita que la cadena tenga una terminación nula, en alguna implementación puede resultar mejor que c_str ().
las cadenas no tienen que estar compuestas necesariamente por datos de caracteres, pueden estar compuestas por elementos de cualquier tipo. En esos casos data()
es más significativo. c_str()
en mi opinión, solo es realmente útil cuando los elementos de su cadena están basados en caracteres.
Extra : En C ++ 11 en adelante, ambas funciones deben ser iguales. data
es decir, ahora se requiere que tenga terminación nula. Según cppreference : "La matriz devuelta tiene terminación nula, es decir, data () y c_str () realizan la misma función".
.data()
, por lo que ya no son equivalentes para cadenas no constantes.En C ++ 11 / C ++ 0x ,
data()
yac_str()
no es diferente. Y, por lo tanto, tambiéndata()
se requiere tener una terminación nula al final.fuente
std::string
asigne un extrachar
para un seguimiento'\0'
. Cuando lo hagastd::string s("\0");
, amboss.data()[0]
ys.data()[1]
están garantizados para evaluar a 0.Incluso sabiendo que ha visto que ellos hacen lo mismo, o que .data () llama a .c_str (), no es correcto suponer que este será el caso de otros compiladores. También es posible que su compilador cambie con una versión futura.
2 razones para usar std :: string:
std :: string se puede usar tanto para texto como para datos binarios arbitrarios.
Debe usar el método .c_str () cuando esté usando su cadena como ejemplo 1.
Debe usar el método .data () cuando esté usando su cadena como ejemplo 2. No porque sea peligroso usar .c_str () en estos casos, sino porque es más explícito que está trabajando con datos binarios para otros revisando tu codigo.
Posible error al usar .data ()
El siguiente código es incorrecto y podría causar una falla de segmento en su programa:
¿Por qué es común que los implementadores hagan que .data () y .c_str () hagan lo mismo?
Porque es más eficiente hacerlo. La única forma de hacer que .data () devuelva algo que no sea terminado en nulo, sería hacer que .c_str () o .data () copie su búfer interno, o simplemente use 2 búferes. Tener un solo búfer terminado en nulo siempre significa que siempre puede usar solo un búfer interno al implementar std :: string.
fuente
Ya se ha respondido, algunas notas sobre el propósito: Libertad de implementación.
std::string
las operaciones, por ejemplo, iteración, concatenación y mutación de elementos, no necesitan el terminador cero. A menos que pase elstring
a una función que espera una cadena terminada en cero, se puede omitir.Esto permitiría que una implementación haga que las subcadenas compartan los datos de la cadena real:
string::substr
podría contener internamente una referencia a los datos de la cadena compartidos y el rango de inicio / fin, evitando la copia (y la asignación adicional) de los datos de la cadena real. La implementación diferiría la copia hasta que llame a c_str o modifique cualquiera de las cadenas. Nunca se haría ninguna copia si se leyeran las cadenas involucradas.(La implementación de copia en escritura no es muy divertida en entornos multiproceso, además, los ahorros típicos de memoria / asignación no valen la pena el código más complejo hoy en día, por lo que rara vez se hace).
Del mismo modo,
string::data
permite una representación interna diferente, por ejemplo, una cuerda (lista enlazada de segmentos de cuerda). Esto puede mejorar significativamente las operaciones de inserción / reemplazo. nuevamente, la lista de segmentos tendría que colapsarse en un solo segmento cuando llamec_str
odata
.fuente
Cita de
ANSI ISO IEC 14882 2003
(C ++ 03 Standard):fuente
Todos los comentarios anteriores son coherentes, pero también me gustaría agregar que a partir de c ++ 17, str.data () devuelve un char * en lugar de const char *
fuente
const
y lasnon-const
sobrecargas están disponibles desde C ++ 17.