Чтение \ r (возврат каретки) vs \ n (новая строка) из консоли с помощью getc?

18

Я пишу функцию, которая в основном ждет, когда пользователь ударит «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. Мне кажется, что '\n' соответствует тому, что я нажимаю кнопку ввода с консоли. Может кто-то объяснить разницу? Кроме того, чтобы проверить, записывая его как if... == "\n" , будет означать буквенный символ символа? то есть пользователю буквально нужно будет ввести "\n" из консоли, исправить?

    
задан MCP 08.04.2012 в 01:15
источник
  • Связанный: stackoverflow.com/questions/1355095/... –  Mysticial 08.04.2012 в 01:20
  • C применяет экраны как к одиночным, так и к двойным кавычкам, поэтому «\ n» - это строка длиной два символа, сначала являющаяся ASCII-кодом 10 (самой \ n), а вторая - ASCII NUL (нулевой терминатор). –  toriningen 08.04.2012 в 01:30
  • (Надеюсь, вы не против изменений в заголовке, они там, чтобы сделать его более доступным для поиска.) –  Apr 7 '12 at 23:32 08.04.2012 в 01:32
  • И вы не можете проверить равенство строк в C с помощью ==, вам нужно использовать strcmp или подобное. char * s1, * s2; if (s1 == s2) {...} просто проверит, будут ли s1 и s2 указывать на одну и ту же область памяти независимо от фактического содержимого памяти. –  toriningen 08.04.2012 в 01:32
  • Если ваш стандартный ввод открывается в текстовом режиме, ваше приложение всегда будет видеть \ n для новой строки, независимо от того, что \ n означает в вашем наборе символов выполнения, и, тем не менее, платформа сериализует новые строки. –  Kerrek SB 08.04.2012 в 02:14

5 ответов

29

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

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

    
ответ дан Whymarrh 08.04.2012 в 01:21
источник
13

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

Окно

Ожидает, что новая строка будет состоять из двух символов: \ r \ n.

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

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

Классическая Mac OS

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

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

    
ответ дан josephthomas 08.04.2012 в 01:24
источник
  • Mac отличается в зависимости от версии newline. –  Jesse Good 08.04.2012 в 01:27
  • Я предполагаю, что вы имели в виду Classic Mac OS для новой строки '\ r', поскольку современная Mac OS X является UNIX и использует '\ n' новую строку. –  toriningen 08.04.2012 в 01:27
  • Вы оба правы, я должен был быть более конкретным. –  josephthomas 08.04.2012 в 01:29
2

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

    
ответ дан Alex Measday 08.04.2012 в 06:56
источник
0

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

    
ответ дан Joshua Michael Calafell 10.11.2014 в 23:01
источник
  • Это должен быть комментарий, а не ответ –  Pranjal 03.06.2016 в 19:43
0

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

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

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

    
ответ дан Tong Zhou 07.01.2018 в 19:40
источник