Правила для символов строки строки С++
Каковы правила для 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>
подход конструктора, но он по крайней мере избавляется от символов '
и ,
.