Para las cadenas C normales, un carácter nulo '\0'
significa el final de los datos.¿Puede una cadena std :: contener nulos incorporados?
¿Qué pasa con std::string
, puedo tener una cadena con caracteres nulos incrustados?
Para las cadenas C normales, un carácter nulo '\0'
significa el final de los datos.¿Puede una cadena std :: contener nulos incorporados?
¿Qué pasa con std::string
, puedo tener una cadena con caracteres nulos incrustados?
Sí puede tener nulos incrustados en su std::string
.
Ejemplo:
std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);
Nota: std::string
's c_str()
miembro siempre anexar un carácter nulo al char buffer devuelto; Sin embargo, el miembro std::string
data()
puede o no agregar un carácter nulo al búfer char devuelto.
Tenga cuidado del operador + =
Una cosa a tener en cuenta es no utilizar operator+=
con un char*
en el lado derecho. Solo se sumará hasta el carácter nulo.
Por ejemplo:
std::string s = "hello";
s += "\0world";
assert(s.length() == 5);
La forma correcta:
std::string s = "hello";
s += std::string("\0world", 6);
assert(s.length() == 11);
Almacenamiento de datos binarios más común el uso de std :: vector
lo general, es más común el uso std::vector
a almacenar datos binarios arbitrarios.
std::vector<char> buf;
buf.resize(1024);
char *p = &buf.front();
es probablemente más común, ya que std::string
's data()
y c_str()
elementos de retorno punteros const lo que la memoria no es modificable. con & buf.front() puede modificar directamente el contenido del búfer.
En C++ 9x '& s.front()' también se puede modificar y se garantiza que apunta a un búfer contiguo. Si bien no existía dicha garantía en C++ 03, no hay implementaciones conocidas de C++ para las cuales no era cierto en la práctica (que es en parte la razón por la cual se agregó a C++ 0x tan rápidamente). –
Tenga en cuenta que a partir de C++ 11, '.c_str()' y '.data' son sinónimos. En particular, esto significa que la cadena devuelta por '.data' debe tener un terminador nulo adjunto. – nneonneo
@PavelMinaev: Supongo que "C++ 9x" fue un error tipográfico para "C++ 0x" (que se convirtió en C++ 11 después de publicar su comentario). –
Sí, esto es válido.
Puede tener un carácter nulo en el medio de la cadena.
Sin embargo, si se utiliza un std :: string con un carácter nulo en el medio con la cadena AC función estás en la ciudad comportamiento no definido - y nadie quiere estar ahí !!!:
int n = strlen(strWithNullInMiddle.c_str()); // Boom!!!
'strlen' solo devolver el número de caracteres antes del primer nulo. Puede ser un comportamiento no anticipado, pero no está indefinido. –
Sí. Una std :: string es solo un vector<char>
con beneficios.
Sin embargo, tenga cuidado acerca de pasar una bestia a algo que llama .c_str()
y se detiene en la 0.
El primero no es cierto, como aprendí recientemente. El intercambio de vectores conserva los iteradores y las referencias a los contenidos, las cadenas no son necesariamente. http://stackoverflow.com/questions/25201758/stringswap-complexity-under-visual-studio – Notinlist
@Notinlist: ¡También tiene un nombre diferente! Oh, el horror –
Se puede, pero ¿por qué querrías? Incrustar NUL en std :: string es solo un problema, porque las funciones a las que pasas std :: string pueden usar su miembro c_str(), y la mayoría supondrá que el primer NUL indica el final de la cadena. Por lo tanto, esta no es una buena idea para hacer. También tenga en cuenta que en UTF-8, solo '\ 0' dará como resultado un 0, por lo que incluso para propósitos i18n, no hay justificación para incrustar NUL.
Gracias por explicar por qué * no * para hacerlo. – Snoopy
No, es tonto. "No use el rango completo de la funcionalidad de' std :: string', porque _puede pasar el resultado de 'c_str()' a las funciones de C-string sin pasar también una longitud ", ¿en serio? Bueno, si nunca haces eso, estarás bien ... –
Ver [std :: string equivalente para datos con caracteres NULL?] (Http://stackoverflow.com/questions/1534335/stdstring-equivalent-for-data-with-null-characters) –