Вопрос по stdin, c, input, newline – read () из stdin не игнорирует перевод строки

4

Я использую следующее условное утверждение для чтения из стандартного ввода.

if ((n = read(0,buf,sizeof(buf))) != 0)

При вводе данных из стандартного ввода, как правило, пользователь нажимает ввод по завершении. Ноread() считает & n; в качестве ввода тоже в этом случаеn = 1 и условное не оценивается как ложное. Есть ли способ сделать условную оценку ложной, когда пользователь нажимает ввод (без ввода чего-либо) на стандартном вводе, кроме проверки содержимого buf. Есть ли другая функция, кромеread() что я могу использовать для этого ??

В этом отношении, что может быть способом для чтения, чтобы определить конец ввода, когда вход поступает со стандартного ввода (стандартное ввод)?

Что ты пытаешься сделать? Читать каждого персонажа по одному? GManNickG
Нет, как вы можете видеть из условия, я читаю из стандартного ввода в буфер (и, может быть, просто записываю его обратно в стандартный вывод). Я хочу остановиться, когда пользователь ничего не вводит и просто нажимает ввод. s_itbhu
По сути, я хотел знать, возможно ли завершить работу в конце строки из стандартного ввода без проверки буфера. Как и в случае, если я читаю из файла, когда происходит EOF, вызов чтения автоматически завершается. В этом случае нет необходимости проверять содержимое буфера. s_itbhu
Ах, теперь я вижу. Я прочитал это неправильно. GManNickG
Пожалуйста, объясните, почему вы ищете способ определения пустой строки без проверки буфера. Я действительно не вижу причины для этого. Вы всегда можете написать свою собственную функцию, которая проверяет буфер, но возвращает 0 в конце файла, -1 в случае ошибки,and '\n' на пустой строке. Если вы читаете свой буфер символ за символом, тогда вы можете использовать стандартную функцию для этой цели из коробки; но тогда это эквивалентно проверке вашего буфера ;-). Inshallah

Ваш Ответ

5   ответов
1

например

while((n = read(0,buf,sizeof(buf))) > 0) {
  if(buf[0] == '\n') // won't handle pressing 9 spaces and then enter
    continue;
  ... process input

}

или используйте, например, fgets, и просто удалите \ n

while(fgets(buf,sizeof buf,stdin) != NULL) {
  char *ptr;
  size_t len;

  if((ptr = strchr(buf,'\n')) != NULL) //strip newline
    *ptr = 0; 
  len = strlen(buf);
  if(len == 0)
   continue;
  ... process input 
}
8

When inputting data from standard input, generally the user presses enter when done. But read() considers '\n' as input too in which case n = 1 and the conditional doesn't evaluate to false.

Первый пункт, безусловно, верно. Клавиша ввода эквивалентна клавише новой строки, поэтому, когда пользователь нажимает клавишу ввода, клавиатура генерирует символ новой строки, иread() поэтому функция возвращает этот символ. Крайне важно, чтобы он это сделал.

Следовательно, ваше условие ошибочно - пустая строка будет содержать символ новой строки и, следовательно, количество байтов будет равно единице. Действительно, есть только один способ получитьread() вызов для возврата 0, когда стандартным вводом является клавиатура, и это для ввода 'EOF'; символ - обычно control-D в Unix, control-Z в DOS. В Unix этот символ интерпретируется драйвером терминала как «отправка предыдущих входных данных в программу, даже если еще нет новой строки». И если пользователь больше ничего не набрал в строке, то возврат изread() будет ноль. Если входные данные поступают из файла, то после прочтения последних данных последующие чтения вернут 0 байтов.

Если вход поступает из канала, то после прочтения всех данных в каналеread() вызов будет блокироваться до тех пор, пока не будет закрыт последний дескриптор файла, который может записать в канал; если этот дескриптор файла находится в текущем процессе, тоread() будет висеть вечно, хотя зависший процесс никогда не сможетwrite() к дескриптору файла - конечно, при условии однопоточного процесса.

Важно то, что вы учите, почему возвращаемое значение 0 из read () / recv () отличается от пустой строки. Если вы получаете 0 от read () / recv (), это означает, что вы находитесь в конце всех входных данных (то есть он закрыт, новый вход не может быть добавлен).
NB: есть устройства, которые получаютread() возвращение нуля не означает, что больше нельзя вводить. Показаны мои древности - магнитные магнитофоны были одним из таких. В настоящее время терминалы - это другое. С эзотерическими опциями наopen() (например, O_NONBLOCK), вы можете получить такое поведение на других устройствах. Но пустая строка по определению является строкой, содержащей только символ новой строки - маркер конца строки (он же символ новой строки) является частью данных. Если вы не хотите этого в своей программе, вы должны удалить его. Толькоgets() удаляет новую строку для вас, но вы должныnever использовать его в производственном коде.
0

что нет способа сделать это без изучения содержимого буфера. Даже readline () делает именно это. В любом случае, почему вы против этого?

0

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

Однако, если есть новая строка, вы можете быть уверены, что это последний символ в строке, поэтому его легко удалить.

Во-первых, я работаю с файловыми дескрипторами, а не с файловыми указателями. fgets () принимает файловые указатели. И что я хочу сделать, это сделать условное выражение ложным, когда пользователь нажимает ввод. Я могу, конечно, здесь определить, был ли символ новой строки последним введенным символом или нет. s_itbhu
@Inshalla Я имел в виду, что если символ новой строки находится в буфере, это, безусловно, последний символ. Я отредактирую свой пост, чтобы сделать его явным.
Вы сказали, что читаете со стандартного ввода, поэтому не имеет значения, используете ли вы read (0, ..) или fread (..., stdin) или fgets (..., stdin). Мой пост был основан на информации, которую вы указали в своем вопросе. Если вы хотите остановиться на пустой строке, вы можете сделать это, как & quot; if (& quot; \ n & apos;! = * Fgets (buf, sizeof (buf) -1, stdin)) & quot;
Вы не можете быть уверены, что последний символ в буфере является новой строкой, поскольку fgets () будет хранить новую строку только в том случае, если она есть в файле. Может не быть, если последняя строка не содержит ни одной.
@qrdl, который, конечно, также проверяет буфер, но может быть предпочтительнее других решений по эстетическим причинам.
2

>1 вместо!=0

единственные ложные срабатывания - односимвольные ответы с последующим прерыванием (EOF)

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