read () из stdin не игнорирует перевод строки

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

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

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

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

 s_itbhu07 авг. 2009 г., 06:33
По сути, я хотел знать, возможно ли завершить работу в конце строки из стандартного ввода без проверки буфера. Как и в случае, если я читаю из файла, когда происходит EOF, вызов чтения автоматически завершается. В этом случае нет необходимости проверять содержимое буфера.
 s_itbhu06 авг. 2009 г., 09:20
Нет, как вы можете видеть из условия, я читаю из стандартного ввода в буфер (и, может быть, просто записываю его обратно в стандартный вывод). Я хочу остановиться, когда пользователь ничего не вводит и просто нажимает ввод.
 GManNickG06 авг. 2009 г., 09:04
Что ты пытаешься сделать? Читать каждого персонажа по одному?
 Inshallah06 авг. 2009 г., 09:30
Пожалуйста, объясните, почему вы ищете способ определения пустой строки без проверки буфера. Я действительно не вижу причины для этого. Вы всегда можете написать свою собственную функцию, которая проверяет буфер, но возвращает 0 в конце файла, -1 в случае ошибки,and '\n' на пустой строке. Если вы читаете свой буфер символ за символом, тогда вы можете использовать стандартную функцию для этой цели из коробки; но тогда это эквивалентно проверке вашего буфера ;-).
 GManNickG06 авг. 2009 г., 09:23
Ах, теперь я вижу. Я прочитал это неправильно.

Ответы на вопрос(5)

например

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 
}
Решение Вопроса

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() к дескриптору файла - конечно, при условии однопоточного процесса.

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

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

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

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

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

>1 вместо!=0

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

Ваш ответ на вопрос