2012-04-07 15 views
17

estoy escribiendo una función que, básicamente, espera a que el usuario pulsa "Enter" y luego hace algo. Lo que he encontrado que funciona cuando la prueba es el siguiente:Lectura r (retorno de carro) vs n (nueva línea) desde la consola con getc?

#include <stdio.h> 

int main() 
{ 
     int x = getc(stdin); 
     if (x == '\n') { 
       printf("carriage return"); 
       printf("\n"); 
     } 
     else { 
       printf("missed it"); 
       printf("\n"); 
     } 
} 

La pregunta que tengo, y lo que he intentado en un principio era hacer: if (x == '\r') pero en las pruebas, el programa no me coge oprimir la tecla Enter. El '\n' parece corresponderme al presionar enter desde la consola. ¿Alguien puede explicar la diferencia? Además, para verificar, escribirlo como if... == "\n" significaría la cadena de caracteres literal? es decir, el usuario tendría que ingresar literalmente al "\n" desde la consola, ¿correcto?

+0

Relacionados: http://stackoverflow.com/questions/1355095/what-is-the-difference-between-r-and-n – Mysticial

+1

C aplica escapes a literales simples y dobles, por lo que "\ n" es ensartar dos caracteres de longitud, primero el código ASCII 10 (\ n en sí) y el segundo - ASCII NUL (terminador nulo). – toriningen

+1

(Espero que no te importe la edición del título, están ahí para que sea más fácil de buscar.) –

Respuesta

26

\n es el carácter de nueva línea, mientras que \r es el retorno de carro. Difieren en lo que los usa. Windows utiliza para significar \r\n la tecla enter se ha pulsado, mientras que Linux y Unix utilizan \n para significar que la tecla enter se ha pulsado.

Por lo tanto, siempre usaría \n porque se utiliza por todos; y if (x == '\n') es la forma correcta de probar la igualdad de caracteres.

13

El '\ n' es el "avance de línea" y '\ R' es el retorno de carro. Los diferentes sistemas operativos van a manejar las nuevas líneas de una manera diferente, como

de Windows

Espera una nueva línea sea la combinación de dos caracteres, '\ r \ n'.

Linux \ Unix y Mac OS moderna

utiliza un solo '\ n' para una nueva línea.

Classic Mac OS

utiliza un solo '\ r' para una nueva línea.

Básicamente, me gustaría utilizar if (x == '\n') ya que es utilizado actualmente por todos los sistemas operativos modernos.

+0

Mac es diferente según la versión [nueva línea] (http://en.wikipedia.org/wiki/Newline). –

+3

Supongo que se refería al Mac OS clásico para la línea nueva '\ r', ya que el Mac OS X moderno es UNIX y utiliza '\ n' nueva línea. – toriningen

+0

Ambos son correctos, debería haber sido más específico. – josephthomas

2

También recuerde que si escribe 25 caracteres y Enter, el primer getc no regresará hasta que los 25 caracteres hayan sido ingresados ​​y presione Enter. Leer un personaje en el momento de escribirlo requiere un código específico de la plataforma. En consecuencia, es mejor que solo lea la línea completa ejecutando fgets en una cadena, recortando la nueva línea y procesando la línea de entrada como un todo.

0

El uso de gets() lo abre a los exploits de desbordamiento de búfer y, en consecuencia, posiblemente a los ataques de código de shell. Debe usar fgets() y pasar en un tamaño de búfer.

+3

Esto debería ser un comentario y no una respuesta – Pranjal

0

Existen varios niveles de abstracciones de representar una nueva línea: el tiempo de ejecución del lenguaje de programación, el editor de texto y el sistema operativo. CR (retorno de carro) y LF (avance de línea) son dos charactores de control que se definen en ASCII. Algunas otras codificaciones de los charadores también pueden definir un carácter de "nueva línea". La tecla Intro en cualquier teclado transmite un significado de "al principio de la siguiente línea". El teclado decide cómo asignar la tecla Intro a su charactor o charactor de control correspondiente. Algunos teclados también diferencian las teclas Intro y Retorno - deje que la tecla Intro sea nueva y la tecla Intro sea el retorno del carro.En un teclado ANSI estándar, solo hay una tecla Intro, que está asignada a un caracter de retorno de carro (13) en ASCII. Así que este es el contenido real que el dispositivo envía al sistema operativo. Sin embargo, diferentes SO deciden interpretar la tecla Enter de forma diferente. Por lo tanto, en el sistema tipo Unix, cualquier retorno de carro se traduce a un operador de alimentación de línea (10 en ASCII) antes de entregarlo al programa que recibe la entrada. Y en Windows, un CR se traduce en dos caracteres: un CR seguido de un LF. Sin embargo, puede configurar el flujo de entrada para que sea el modo raw, en cuyo caso el programa obtiene lo que el teclado realmente envía. Ahora el editor entra en juego. Cuando el editor recibe un CR de stdin en modo raw, sabe que el CR corresponde a la tecla Enter del teclado (supuesto sobre el teclado) y se supone que debe mostrar una nueva línea en la pantalla. En el modo raw, debe llamar a la llamada del sistema de escritura para generar un CR + LF. Si el flujo de salida no está en modo raw, el editor de texto debe emitir la secuencia específica del sistema operativo, como LF en Linux.

Finalmente, el tiempo de ejecución del lenguaje también puede interpretar la nueva línea a su manera. Por ejemplo, el estándar de C dice: Al escribir un archivo en modo de texto, '\ n' se traduce de forma transparente a la secuencia de línea nueva nativa utilizada por el sistema, que puede ser más larga que un carácter. Al leer en modo texto, la secuencia de nueva línea nativa se traduce de nuevo a '\ n'. En el modo binario, no se realiza ninguna traducción, y la representación interna producida por '\ n' se envía directamente. Tenga en cuenta que '\ n' y '\ r' son caracteres específicos del lenguaje que representan LF y CR, respectivamente, que son populares en los lenguajes tipo C. Pero no todos los idiomas tienen que usar esta notación.

Para su segunda pregunta, "\ n" es '\ n' seguido de un terminador '\ 0'. No hay forma de ingresar un '\ 0' desde la consola.

Cuestiones relacionadas