web-dev-qa-db-fra.com

Règles pour le caractère d'échappement littéral de chaîne C++

Quelles sont les règles pour le caractère d'échappement \ dans les littéraux de chaîne? Existe-t-il une liste de tous les caractères qui ont été échappés?

En particulier, lorsque j’utilise \ dans un littéral de chaîne dans gedit et que je le suis avec trois nombres quelconques, cela les colore différemment.

J'essayais de créer un std::string construit à partir d'un littéral avec le caractère 0 suivi du caractère nul (\0), suivi du caractère 0. Cependant, la syntaxe en surbrillance m'a averti que cela créerait peut-être quelque chose comme le caractère 0 suivi du caractère nul (\00, également appelé \0), c'est-à-dire seulement deux caractères.

Pour la solution à ce seul problème, est-ce la meilleure façon de le faire:

std::string ("0\0" "0", 3)  // String concatenation 

Et y a-t-il une référence à ce que le caractère d'échappement fait dans les chaînes de caractères en général? Qu'est-ce que '\ a', par exemple?

37
David Stone

Caractères de contrôle:

(Les codes hexadécimaux supposent un codage de caractères compatible ASCII.)

  • \a = \x07 = alerte (cloche)
  • \b = \x08 = retour arrière
  • \t = \x09 = onglet horizontal
  • \n = \x0A = nouvelle ligne (ou saut de ligne)
  • \v = \x0B = onglet vertical
  • \f = \x0C = flux de formulaire
  • \r = \x0D = retour chariot
  • \e = \x1B = escape (extension GCC non standard)

Caractères de ponctuation:

  • \" = guillemet (barre oblique inverse non requise pour '"')
  • \' = apostrophe (barre oblique inverse non requise pour "'")
  • \? = point d'interrogation (utilisé pour éviter les trigraphes)
  • \\ = barre oblique inverse

Références de caractères numériques:

  • \ + jusqu'à 3 chiffres octaux
  • \x + un nombre quelconque de chiffres hexadécimaux
  • \u + 4 chiffres hexadécimaux (Unicode BMP, nouveauté C++ 11)
  • \U + 8 chiffres hexadécimaux (plans astraux Unicode, nouveauté C++ 11)

\0 = \00 = \000 = ecape octal pour caractère nul

Si vous voulez un caractère après un \0, alors oui, je vous recommande la concaténation de chaînes. Notez que les espaces entre les parties du littéral sont facultatifs. Vous pouvez donc écrire "\0""0".

55
dan04

\a est le caractère cloche/alerte qui, sur certains systèmes, déclenche un son. \nnn représente un caractère arbitraire ASCII en base octale. Cependant, \0 est spécial en ce sens qu'il représente le caractère null quoi qu'il arrive.

Pour répondre à votre question initiale, vous pouvez également échapper à vos caractères '0', tels que:

std::string ("\060\000\060", 3);

(étant donné qu'un ASCII '0' correspond à 60 octal)

La documentation MSDN contient un article assez détaillé, ainsi que cppreference

4
jli

\ 0 sera interprété comme une séquence d'échappement octale s'il est suivi d'autres chiffres, ainsi\00 sera interprété comme un seul caractère. (\ 0 est techniquement une séquence d'échappement octale également, au moins en C).

La façon dont vous le faites:

std::string ("0\0" "0", 3)  // String concatenation 

fonctionne car cette version du constructeur prend un tableau de caractères; si vous essayez simplement de passer "0\0" à "0" en tant que const char *, il la traitera comme une chaîne C et ne copiera que tout jusqu'au caractère null.

Voici une liste de séquences d'échappement .

4
mgiuffrida

J'ai laissé quelque chose comme ceci en commentaire, mais j'estime qu'il faut probablement plus de visibilité, car aucune des réponses ne mentionne cette méthode:

La méthode que je préfère maintenant pour initialiser un std::string avec des caractères non imprimables en général (et des caractères nuls incorporés en particulier) consiste à utiliser la fonctionnalité C++ 11 des listes d'initialisation.

std::string const str({'\0', '6', '\a', 'H', '\t'});

Je ne suis pas obligé d'effectuer un comptage manuel source d'erreurs du nombre de caractères que j'utilise. Par conséquent, si je souhaite ultérieurement insérer un "\ 013" au milieu quelque part, je peux et tout mon code fonctionnera toujours. . Cela évite aussi complètement l'utilisation accidentelle d'une mauvaise séquence d'échappement.

Le seul inconvénient est tous ces caractères supplémentaires ' et ,.

1
David Stone

Avec la magie des littéraux définis par l'utilisateur, nous avons encore une autre solution à cela. C++ 14 a ajouté un opérateur std::string littéral.

using namespace std::string_literals;
auto const x = "\0" "0"s;

Construit une chaîne de longueur 2, avec un caractère '0' (null) suivi d'un caractère '0' (le chiffre zéro). Je ne suis pas sûr que ce soit plus ou moins clair que l'approche initializer_list<char>constructeur , mais au moins elle supprime les caractères ' et ,.

0
David Stone