Почему escape-символы не работают, когда я читаю cin?

(А)

string str = "Hello\nWorld";

Когда я печатаю str, вывод:

Hello
World

(Б)

string str;
cin >> str;      //given input as Hello\nWorld

Когда я печатаю str, вывод:

Hello\nWorld

В чем разница между (а) и (б)?

Ответ 1

Компилятор C++ имеет определенные правила, когда предоставляются управляющие символы - документация. Как вы можете видеть, когда вы указываете \n в строковом литерале, он заменяется компилятором с помощью строки (значение 0xa для ASCII). Таким образом, вместо 2 символов, \ и n, вы получаете один символ с двоичным кодом 0xa (я предполагаю, что вы используете кодировку ASCII), что заставляет консоль выводить на новую строку при печати. Когда вы читаете строку, компилятор не участвует, и ваша строка содержит фактические символы \ и n в ней.

Ответ 2

Если указано в строковом литерале, "\n" будет переведено в соответствующий код ascii (0x0a на linux) и сохранен как есть. Он не будет храниться как обратная косая черта, за которым следует буква n. Последовательности Escape предназначены только для вас, чтобы позволить строковые литералы со встроенными символами новой строки.

С другой стороны, ваша оболочка, работающая в терминале, не выполняет такую подстановку: она отправляет буквальную обратную косую черту и n, которая будет напечатана как таковая.

Чтобы напечатать новую строку, введите новую строку:

$ echo "Hello
 World" | ./your-program 

Ответ 3

Строка в cout << "Hello\nworld" преобразуется компилятором в скомпилированную строку, где escape-коды преобразуются в символы, поэтому функция cout при выполнении не видит строку с двумя символами "\n", но эквивалентный код для следующий линия знак.

Но cin получает строку каждого типизированного символа во время выполнения и не конвертирует escape-коды. Поэтому, если вы хотите конвертировать эти коды эвакуации, вам нужно выполнить функцию замены.

Ответ 4

cin не включает компилятор C++. Эквивалентные последовательности в строковых литералах являются особенностью C++ lexer, которая является частью компилятора C++. Потоки более или менее дают вам то, что пришло из ОС (они могут делать некоторые переводы CRLF → CR или аналогичные на основе ОС, но это они).

Ответ 5

Почему escape-символы не работают, когда я читаю cin?

Поскольку потоковые считыватели определены таким образом. В основе каждого символа читается отдельно. Только функции более высокого уровня придавали персонажу дополнительное значение.

Когда компилятор обрабатывает строковый литерал "Hello\nWorld", его файловый читатель передает ему два символа. Только компилятор/парсер C++ переводит их в один символ на основе правил языка.

Ответ 6

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

Если вы хотите обработать строку, чтобы интерпретировать escape-последовательности, вам придется сделать это самостоятельно (или использовать соответствующую библиотеку).

Ответ 7

В скомпилированном коде символьный литерал \n заменяется значением, специфичным для реализации, которое система выполнения рассматривает как символ новой строки. Определение языка не требует какого-либо конкретного значения.

При чтении ввода с консоли или файла входящий текст не компилируется, а последовательность символов "\n" не имеет особого значения. Это всего лишь два символа.