Обработка Backsla sh Escape-последовательностей в C - PullRequest
1 голос
/ 13 февраля 2020

Я смотрел на пример в своих слайдах курса, который не имел большого объяснения.

char getchar_escaped(void)
{
   char c;
   if ((c = getchar()) != '\\') return c;

   switch ((c = getchar())) {
     case '\\':
       return '\\';
     case 'n':
       return '\n';
     default:
       return c;
   }
}

Что именно происходит в этом коде? Как это относится к переводу строки и двойным слешам?

Ответы [ 3 ]

2 голосов
/ 13 февраля 2020

В C символьных строковых литералах и односимвольных константах есть ряд «специальных» символов, которые не могут быть легко представлены в тексте исходного кода. Примерами являются символ символ новой строки , символ nul (терминатор) и символ возврата каретки .

. Этот язык позволяет нам кодерам включать такие символы с помощью escape-последовательности - которые вводятся с помощью символа backsla sh (\), за которым следует соответственно описательный «обычный» символ. Таким образом, мы можем указать символ newline , используя 'экранированный' 'n', например: char NewLine = '\n'; аналогично nul и возврат каретки символов представлены \0 и \r соответственно.

Однако это соглашение вызывает проблему, когда мы на самом деле хотим указать сам символ backsla sh! Итак, для этого мы указываем escape-последовательность, где вторым символом является и обратный слеш; таким образом, код char BackSlash = '\\'; присваивает BackSlash значение (вероятно, ASCII, но не обязательно) самого backsla sh.

В вашем коде тест после first c = getchar() проверяет наличие входного символа backsla sh - который, если найден, сигнализирует о начале одной из этих "escape-последовательностей" - если она не найдена, мы можем просто вернуть фактический ввод символов. Однако, если мы, таким образом, обнаруживаем начало escape-последовательности, нам нужно проверить следующий символ: если это «n» (case 'n':), мы возвращаем escape-последовательность, представляющую символ новой строки (return '\n';); если это другой backsla sh (case '\\':), мы возвращаем последовательность для фактического backsla sh (return '\';).

Другие стандартные escape-последовательности не являются ' не обнаружены в вашем коде, но было бы тривиально добавить дополнительные проверки для них.

Пожалуйста, не стесняйтесь просить дальнейших разъяснений и / или объяснений.

1 голос
/ 13 февраля 2020

\ имеет особое значение. Обычно это меняет значение следующего символа. Пример: \n означает новую строку, которая на самом деле является символом ASCII. Но поскольку \ означает «изменить следующий символ», то как вы могли бы получить буквальный символ \? Изменяя его с \, делая \\. Это значит "взять буквальный символ \".

char getchar_escaped(void)
{
   char c;
   // read a char from the input if it is the '\' character than return with it
   if ((c = getchar()) != '\\') return c; 
   switch ((c = getchar())) { // read in another character
   case '\\': return '\\'; // if it a '\' character then return '\'
   case 'n': return '\n'; // if it an 'n' than return the new line character: '\n'
   default: // otherwise
   return c; // just return the character that was read
   }
}
0 голосов
/ 13 февраля 2020

Существует два различных использования escape-последовательностей backsla sh в опубликованном вами коде.

  1. C использует escape-последовательности backsla sh как часть грамматики C язык для представления определенных символьных значений в символьной константе или строковом литерале. В символьной константе или строковом литерале последовательность \\ представляет один символ обратного знака sh, а последовательность \n представляет один символ новой строки. Есть еще несколько этих escape-последовательностей backsla sh на языке C. За подробностями обращайтесь к справочнику C.

  2. Функция getchar_escaped программы читает символы со стандартного ввода и применяет свои собственные экранирующие правила backsla sh, которые соответствуют правилам Сам язык C в отношении последовательностей \\ и \n. Если в данный момент он не читает escape-последовательность backsla sh и читает символ backsla sh, он читает следующий символ и возвращает символ, соответствующий последовательности backsla sh (например, возвращает символ новой строки, если символ следует обратная сторона sh является n). (На самом деле, n является единственным символом, который не сопоставляется с идентичным символом. Особый случай обработки обратного слэса sh, за которым следует обратный слэс sh, является избыточным.)

...