Правила для символов строки строки С++

Каковы правила для escape-символа \ в строковых литералах? Есть ли список всех символов, которые были экранированы?

В частности, когда я использую \ в строковом литерале в gedit и следую ему любыми тремя числами, он окрашивает их по-разному.

Я пытался создать std::string, построенный из литерала с символом 0, за которым следует нулевой символ (\0), за которым следует символ 0. Однако подсветка синтаксиса предупреждала меня, что, возможно, это создаст нечто вроде символа 0, за которым следует нулевой символ (\00, aka \0), то есть только два символа.

Для решения только этой проблемы это лучший способ сделать это:

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

И есть ли какая-то ссылка на то, что делает escape-символ в строковых литералах вообще? Что такое '\ a', например?

Ответ 1

Управляющие символы:

(Hex-коды предполагают кодировку ASCII-совместимого символа.)

  • \a= \x07= предупреждение (звонок)
  • \b= \x08= backspace
  • \t= \x09= горизонтальная вкладка
  • \n= \x0A= новая строка (или строка)
  • \v= \x0B= вертикальная вкладка
  • \f= \x0C= form feed
  • \r= \x0D= возврат каретки
  • \e= \x1B= escape (нестандартное расширение GCC)

Знаки пунктуации:

  • \"= кавычка (обратная косая черта не требуется для '"')
  • \'= апостроф (обратная косая черта не требуется для "'")
  • \?= знак вопроса (используется для предотвращения триграфов)
  • \\= обратная косая черта

Ссылки на числовые символы:

  • \ + до 3 восьмеричных цифр
  • \x + любое количество шестнадцатеричных цифр
  • \u + 4 шестнадцатеричных разряда (Unicode BMP, новый в С++ 11)
  • \u + 8 шестнадцатеричных цифр (астральные плоскости Юникода, новые в С++ 11)

\0= \00= \000= восьмеричный вылет для нулевого символа

Если вам нужен фактический цифровой символ после \0, то да, я рекомендую конкатенацию строк. Обратите внимание, что пробелы между частями литерала необязательны, поэтому вы можете написать "\0""0".

Ответ 2

\a - символ звонка/предупреждения, который на некоторых системах запускает звук. \nnn, представляет собой произвольный символ ASCII в восьмеричной базе. Однако \0 особенность в том, что он представляет нулевой символ независимо от того, что.

Чтобы ответить на ваш исходный вопрос, вы также можете избежать ваших символов "0", например:

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

(поскольку ASCII '0' равно 60 в восьмеричном)

документация MSDN содержит довольно подробную статью об этом, а также cppreference

Ответ 3

\ 0 будет интерпретироваться как восьмеричная escape-последовательность, если за ней следуют другие цифры, поэтому \00 будет интерпретироваться как один символ. (\ 0 также технически является восьмеричной управляющей последовательностью, по крайней мере, в C).

Как вы это делаете:

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

работает, потому что эта версия конструктора принимает массив char; если вы попытаетесь просто передать "0\0" "0" как const char *, он будет рассматривать его как строку C и только скопировать все до нулевого символа.

Ниже приведен список escape-последовательностей.

Ответ 4

Я оставил что-то вроде этого в качестве комментария, но я чувствую, что он, вероятно, нуждается в большей видимости, поскольку ни один из ответов не упоминает этот метод:

Метод, который я сейчас предпочитаю для инициализации std::string с непечатаемыми символами вообще (и вложенными нулевыми символами в частности), должен использовать функцию С++ 11 списков инициализаторов.

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

Мне не требуется выполнять ручной подсчет количества ошибок, которые я использую, так что если позже я хочу вставить "\ 013" где-то посередине, я могу и весь свой код будет по-прежнему работать. Он также полностью избегает любых проблем с использованием неправильной последовательности эвакуации случайно.

Единственным недостатком являются все те дополнительные символы ' и ,.

Ответ 5

С магией пользовательских литералов у нас есть еще одно решение. В С++ 14 был добавлен оператор std::string literal.

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

Создает строку длиной 2 с символом '\ 0' (нуль), за которым следует символ '0' (цифра нуль). Я не уверен, если он более или менее понятен, чем initializer_list<char> подход конструктора, но он по крайней мере избавляется от символов ' и ,.