web-dev-qa-db-fra.com

Pourquoi std :: string ("\ x00") signale une longueur de 0?

J'ai une fonction qui doit coder des chaînes, qui doit pouvoir accepter 0x00 comme un "octet" valide. Mon programme doit vérifier la longueur de la chaîne, cependant si je passe "\x00" À std::string La méthode length() renvoie 0.

Comment puis-je obtenir la longueur réelle même si la chaîne est un seul caractère nul?

27
Adamski

Vous passez dans une chaîne vide. Utilisez à la place std::string(1, '\0').

Ou std::string{ '\0' } (merci, @ zett42)

29
Sid S

std::string est parfaitement capable de stocker des valeurs nulles. Cependant, vous devez vous méfier, car const char* ne l'est pas, et vous construisez très brièvement un const char*, à partir duquel vous créez le std::string.

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

Cela crée une chaîne C constante contenant uniquement le caractère nul, suivie d'un terminateur nul. Mais les chaînes C ne savent pas combien de temps elles sont; la chaîne pense donc qu'elle s'exécute jusqu'au premier terminateur nul, qui est le premier caractère. Par conséquent, une chaîne de longueur nulle est créée.

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

std::string est null-clean. Personnages (\0) peut également être le zéro octet librement. Donc, ici, rien ne nous empêche de lire correctement la structure des données. La longueur de b sera 1.

En général, vous devez éviter de construire des chaînes C contenant des caractères nuls. Si vous lisez l'entrée d'un fichier directement dans std::string ou assurez-vous de pousser les caractères un par un, vous pouvez obtenir le résultat souhaité. Si vous avez vraiment besoin d'une chaîne constante avec des caractères nuls, pensez à utiliser un autre caractère sentinelle au lieu de \0 puis (si vous vraiment en avez besoin) remplacez ces caractères par '\0' après le chargement dans std::string.

45
Silvio Mayolo

Avec C++ 14, vous pouvez utiliser un opérateur littéral de chaîne pour stocker des chaînes avec des octets nuls:

using namespace std::string_literals;

std::string a = "\0"s;
std::string aa = "\0\0"s; // two null bytes are supported too
24
Erbureth