
s_itbhu
Estoy usando la siguiente declaración condicional para leer desde la entrada estándar.
if ((n = read(0,buf,sizeof(buf))) != 0)
Al ingresar datos desde la entrada estándar, generalmente el usuario presiona enter cuando termina. Pero read()
considera ‘\n’ como entrada también en cuyo caso n = 1
y el condicional no se evalúa como falso. ¿Hay alguna manera de hacer que la evaluación condicional sea falsa cuando el usuario presiona enter (sin ingresar nada) en la entrada estándar además de verificar el contenido de buf. ¿Hay alguna otra función además de read()
que podría usar para este propósito??
De hecho, ¿cuál puede ser una forma de que la lectura determine el final de la entrada cuando la entrada proviene de la entrada estándar (stdin)?
Usted pregunta:
Al ingresar datos desde la entrada estándar, generalmente el usuario presiona enter cuando termina. Pero read() también considera ‘\n’ como entrada, en cuyo caso n = 1 y el condicional no se evalúa como falso.
El primer punto es ciertamente cierto. La tecla Intro es equivalente a la tecla de nueva línea, por lo que cuando el usuario presiona Intro, el teclado genera un carácter de nueva línea y el read()
Por lo tanto, la función devuelve ese carácter. Es crucial que lo haga.
Por lo tanto, su condición es incorrecta: una línea vacía incluirá la nueva línea y, por lo tanto, el recuento de bytes será uno. De hecho, solo hay una manera de obtener la read()
llame para devolver 0 cuando la entrada estándar es el teclado, y eso es para escribir el carácter ‘EOF’, generalmente control-D en Unix, control-Z en DOS. En Unix, el controlador de terminal interpreta ese carácter como “enviar los datos de entrada anteriores al programa incluso si aún no hay una nueva línea”. Y si el usuario no ha escrito nada más en la línea, entonces el retorno de read()
será cero. Si la entrada proviene de un archivo, luego de leer los últimos datos, las lecturas posteriores devolverán 0 bytes.
Si la entrada proviene de una tubería, luego de leer todos los datos en la tubería, el read()
la llamada se bloqueará hasta que se cierre el último descriptor de archivo que puede escribir en la canalización; si ese descriptor de archivo está en el proceso actual, entonces el read()
colgará para siempre, aunque el proceso colgado nunca podrá write()
al descriptor del archivo, suponiendo un proceso de un solo subproceso, por supuesto.

cuarenta y dos
Sólo tipo >1
en vez de !=0
los únicos falsos positivos son respuestas de un solo carácter seguidas de una interrupción (EOF)
Tienes que comprobar el búfer tú mismo. p.ej
while((n = read(0,buf,sizeof(buf))) > 0) {
if(buf[0] == '\n') // won't handle pressing 9 spaces and then enter
continue;
... process input
}
o use, por ejemplo, fgets, y simplemente elimine el \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
}

qrdl
es mejor que uses fgets()
para su tarea (captar la entrada del usuario), pero incluso fgets()
almacena el carácter de nueva línea en el búfer.
Sin embargo, si hay una nueva línea, puede estar seguro de que es el último carácter de la cadena, por lo que es fácil eliminarlo.

Michael Foukarakis
Estoy bastante seguro de que no hay forma de hacerlo sin examinar el contenido del búfer. Incluso readline() hace precisamente eso. ¿Por qué te opones a eso, de todos modos?
¿Que estás tratando de hacer? ¿Leer cada carácter uno a la vez?
– GManNickG
6 de agosto de 2009 a las 7:04
No, como puede ver en el condicional, estoy leyendo de la entrada estándar en un búfer (y tal vez diga que solo lo escribo en la salida estándar). Quiero detenerme cuando el usuario no ingresa nada y solo presiona enter.
– s_itbhu
6 de agosto de 2009 a las 7:20
Ah, ya veo. Lo leí mal.
– GManNickG
6 de agosto de 2009 a las 7:23
Explique por qué está buscando una forma de determinar una línea en blanco sin examinar el búfer. Realmente no veo la razón de ello. Siempre puede escribir su propia función que examina el búfer, pero devuelve 0 al final del archivo, -1 en caso de error, y N’ en una línea en blanco. Si lee su búfer carácter por carácter, entonces puede usar la función estándar para este propósito lista para usar; pero entonces eso es equivalente a examinar tu búfer ;-).
– Inshallah
6 de agosto de 2009 a las 7:30
Básicamente, quería saber si era posible terminar al final de la línea desde la entrada estándar sin examinar el búfer. Como si leyera de un archivo, cuando ocurre EOF, la llamada de lectura finaliza automáticamente. En ese caso, no es necesario comprobar el contenido del búfer.
– s_itbhu
7 de agosto de 2009 a las 4:33