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

4

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

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

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

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

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

Ваш Ответ

5   ответов
2

просто введите>1 вместо!=0

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

8

При вводе данных из стандартного ввода, как правило, пользователь нажимает ввод по завершении. Но read () считает '' в качестве входных данных, в этом случае n = 1 и условное неоценивать как ложное.

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

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

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

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

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

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

Во-первых, я работаю с файловыми дескрипторами, а не с файловыми указателями. fgets () принимает файловые указатели. И что я хочу сделать, это сделать условное выражение ложным, когда пользователь нажимает ввод. Я могу, конечно, здесь определить, был ли символ новой строки последним введенным символом или нет. s_itbhu
Вы сказали, что читаете со стандартного ввода, так что это неНе имеет значения, используете ли вы read (0, ..) или fread (..., stdin) или fgets (..., stdin). Мой пост был основан на информации, которую вы указали в своем вопросе. Если вы хотите остановиться на пустой строке, вы можете сделать это какесли ('\ П» ! = * fgets (buf, sizeof (buf) -1, stdin)) " qrdl
@qrdl: ваше предложение проверить*fgets() не очень хорошая идея; еслиfgets() обнаруживает EOF, возвращает нулевой указатель и разыменование, которое приведет к сбою вашей программы (возможно; формально это вызывает неопределенное поведение, и результат не очень хороший, независимо от того) .I ' Jonathan Leffler
@qrdl, который, конечно, также проверяет буфер, но может быть предпочтительнее других решений по эстетическим причинам. Inshallah
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, и просто скинуть

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 
}
0

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

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