¿Por qué std:: string("x00") reporta una longitud de 0?


Tengo una función que necesita codificar cadenas, que necesita ser capaz de aceptar 0x00 como un 'byte'válido. Mi programa necesita comprobar la longitud de la cadena, sin embargo si paso "\x00" a std::string el método length() devuelve 0.

¿Cómo puedo obtener la longitud real incluso si la cadena es un solo carácter nulo?

Author: Fabio Turati, 2018-01-15

3 answers

Estás pasando una cadena vacía. Utilice std::string(1, '\0') en su lugar.

O std::string{ '\0' } (gracias, @zett42)

 29
Author: Sid S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-14 23:56:05

std::string es perfectamente capaz de almacenar nulos. Sin embargo, hay que tener cuidado, ya que const char* no lo es, y construir muy brevemente un const char*, a partir del cual se crea el std::string.

std::string a("\x00");

Esto crea una cadena C constante que contiene solo el carácter nulo, seguido de un terminador nulo. Pero las cadenas C no saben cuánto tiempo son; por lo que la cadena piensa que se ejecuta hasta el primer terminador nulo, que es el primer carácter. Por lo tanto, se crea una cadena de longitud cero.

std::string b("");
b.push_back('\0');

std::string es null limpio. Los caracteres (\0) pueden ser el byte cero libremente también. Así que, aquí, no hay nada que nos impida leer correctamente la estructura de datos. La longitud de b será 1.

En general, debe evitar construir cadenas C que contengan caracteres nulos. Si lee la entrada de un archivo directamente en std::string o asegúrese de empujar los caracteres uno a la vez, puede obtener el resultado que desea. Si realmente necesita una cadena constante con caracteres nulos, considere usar algunos otro carácter centinela en lugar de \0 y luego (si realmente lo necesita) reemplace esos caracteres con '\0' después de cargar en std::string.

 46
Author: Silvio Mayolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-15 23:41:26

Con C++14, puede usar un operador literal de cadena para almacenar cadenas con bytes nulos:

using namespace std::string_literals;

std::string a = "\0"s;
std::string aa = "\0\0"s; // two null bytes are supported too
 23
Author: Erbureth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-15 09:50:25