Чтение r (возврат каретки) vs n (новая строка) из консоли с getc?

Я пишу функцию, которая в основном ждет, пока пользователь нажмет "enter", а затем что-то сделает. Что я нашел, что работает при тестировании, это ниже:

#include <stdio.h>

int main()
{
        int x = getc(stdin);
        if (x == 'n') {
                printf("carriage return");
                printf("n");
        }
        else {
                printf("missed it");
                printf("n");
        }
}

вопрос у меня есть, и то, что я пытался сначала делать: if (x == 'r') но при тестировании программа не поймала меня, нажав enter. The 'n' Кажется, соответствует мне, нажав enter с консоли. Кто-нибудь может объяснить разницу? Кроме того, чтобы проверить, напишите его как if... == "n" будет означать строку символов литерал? т. е. пользователю буквально придется ввести "n" С консоли, правильно?

5 ответов


\n - Это символ новой строки, в то время как \r возврат каретки. Они различаются в том, что их использует. Windows использует \r\n для обозначения клавиши enter была нажата, в то время как Linux и Unix используют \n для обозначения нажатия клавиши enter.

таким образом, я всегда буду использовать \n потому что он используется всеми; и if (x == '\n') это правильный способ проверить равенство символов.


"\n "- это "подача строки", а "\r " - возврат каретки. Различные операционные системы будут обрабатывать новые строки по-разному, например

Windows

ожидает, что новая строка будет комбинацией двух символов "\r\n".

Linux\Unix и современные Mac OS

использует один '\n ' для новой строки.

классический Mac OS

использует один '\r ' для нового линия.

в принципе, я бы использовал if (x == '\n') Как это в настоящее время используется всеми современными операционными системами.


также помните, что если вы вводите 25 символов и вводите, первый getc не вернется, пока не будут введены все 25 символов, и вы нажмете Enter. Чтение символа во время его ввода требует кода, специфичного для платформы. Следовательно, вам может быть лучше просто прочитать всю строку, выполнив fgets в строку, обрезка новой строки и обработка входной строки в целом.


используя gets() открывает вас для эксплойтов переполнения буфера и, следовательно, возможно, атак кода оболочки. Вы должны использовать fgets() и передать размер буфера.


существует несколько уровней абстракций представления новой строки - среда выполнения языка программирования, текстовый редактор и ОС. CR (возврат каретки) и LF (подача линии) - это два управляющих символа, определенных в ASCII. Некоторые другие кодировки могут также определять символ" новой строки". Клавиша Enter на любой клавиатуре передает значение "к началу следующей строки". Клавиатура решает, как сопоставить клавишу Enter с соответствующим управляющим символом или символами. Некоторая клавиатура также дифференцирует клавишу Enter и Return - пусть клавиша Enter будет новой строкой, а клавиша Return-возвращением каретки. В стандартной клавиатуре ANSI есть только клавиша Enter, которая сопоставляется с символом возврата каретки (13) в ASCII. Таким образом, это фактический контент, который отправляется в ОС устройством. Однако разные ОС по-разному интерпретируют ключ ввода. Таким образом, в Unix-подобной системе, любой возврат каретки перевод строки charator корма (10 в ASCII) до момента передачи в программе это получает входные данные. А в Windows CR переводится на два символа - CR, за которым следует LF. Однако вы можете установить входной поток в режим raw, и в этом случае программа получает то, что фактически отправляет клавиатура. Теперь в игру вступает редактор. Когда редактор получает CR от stdin в режиме raw, он знает, что CR соответствует клавише Enter на клавиатуре (предположение о клавиатуре), и он должен отображать новую строку на экране. В режиме raw он должен вызвать запись системный вызов для вывода CR + LF. Если выходной поток не находится в режиме raw, текстовый редактор должен выводить последовательность, специфичную для ОС, например LF в linux.

наконец, языковая среда выполнения также может интерпретировать новую строку по-своему. Например, стандарт C говорит, что при записи файла в текстовом режиме "\n " прозрачно переводится в собственную последовательность новой строки, используемую системой, которая может быть длиннее одного символа. При чтении в текстовом режиме собственная последовательность новой строки переведено обратно на "\n". В двоичном режиме перевод не выполняется, а внутреннее представление, создаваемое "\n", выводится непосредственно. Обратите внимание, что "\n " и "\r " являются языковыми символами, которые представляют LF и CR соответственно, которые популярны в C-подобных языках. Но не каждый язык должен использовать это обозначение.

для вас второй вопрос: "\n "- это "\n", за которым следует Терминатор "\0". Невозможно ввести "\0"из консоли.