Вопрос по string, c++ – Правила для строковых литералов C ++ экранирующий символ

37

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

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

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

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

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

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

Я не только могу использовать синтаксис списка инициализатора, но и настоятельно рекомендую его при любом другом методе построения строки, который требует указания размера или использования экранированных символов. Рассмотрим тонкое неопределенное поведение, изложенное вstackoverflow.com/questions/164168/… David Stone
Если вам нужен один` just use \`. MPelletier
Связанные, о том, какescape an escape sequence, Лучшее решение - использовать конкатенацию, как у вас. MPelletier
Теперь я понимаю, что мой комментарий в 1:32 полностью запутан ... Понятия не имею, что я имел в виду ... MPelletier
Похоже, я также могу использовать синтаксис списка инициализатора:std::string { '0', 0, '0' }; David Stone

Ваш Ответ

5   ответов
4

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

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

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

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

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
1

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

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

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

Я не обязан выполнять подверженный ошибкам ручной подсчет количества символов, которые я использую, так что, если позже я захочу вставить «\ 013»; где-то посередине, я могу, и весь мой код все еще будет работать. Это также полностью обходит любые проблемы, связанные с неправильным использованием escape-последовательности.

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

56

Control characters:

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

\a = \x07 = alert (bell) \b = \x08 = backspace \t = \x09 = horizonal tab \n = \x0A = newline (or line feed) \v = \x0B = vertical tab \f = \x0C = form feed \r = \x0D = carriage return \e = \x1B = escape (non-standard GCC extension)

Punctuation characters:

\" = quotation mark (backslash not required for '"') \' = apostrophe (backslash not required for "'") \? = question mark (used to avoid trigraphs) \\ = backslash

Numeric character references:

\ + up to 3 octal digits \x + any number of hex digits \u + 4 hex digits (Unicode BMP, new in C++11) \U + 8 hex digits (Unicode astral planes, new in C++11)

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

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

Error: User Rate Limit Exceeded\eError: User Rate Limit Exceeded\x1BError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded\xError: User Rate Limit ExceededdoError: User Rate Limit Exceeded"\x0020" "FeedDadBeer"Error: User Rate Limit Exceeded"\x0020FeedDadBeer".
Error: User Rate Limit Exceeded\xError: User Rate Limit Exceeded\x5fError: User Rate Limit Exceeded01011111Error: User Rate Limit Exceeded11110101Error: User Rate Limit Exceeded\x5Error: User Rate Limit Exceeded01010000Error: User Rate Limit Exceeded00000101Error: User Rate Limit Exceeded\x5f5Error: User Rate Limit Exceeded01011111 01010000Error: User Rate Limit Exceeded01011111 00000101?
Error: User Rate Limit Exceeded"\e"Error: User Rate Limit Exceeded\x1B?
4

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

То, как вы это делаете:

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

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

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

0

. C ++ 14 добавилstd::string буквальный оператор.

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

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

Похожие вопросы