2012-04-07 9 views
17

Sto scrivendo una funzione che sostanzialmente aspetta che l'utente prenda "invio" e poi faccia qualcosa. Quello che ho trovato che funziona quando il test è il seguito:Lettura r (ritorno a capo) vs n (newline) dalla console 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 domanda che ho, e quello che ho provato in un primo momento è stato quello di fare: if (x == '\r') ma in fase di test, il programma non mi cattura premendo invio. Il '\n' sembra corrispondere a me premendo Invio dalla console. Qualcuno può spiegare la differenza? Inoltre, per verificare, scriverlo come if... == "\n" significherebbe la stringa di caratteri letterale? vale a dire che l'utente dovrebbe letteralmente inserire "\n" dalla console, corretto?

+0

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

+1

C applica gli escape a letterali sia singoli che doppi, quindi "\ n" è stringa due caratteri di lunghezza, il primo è il codice ASCII 10 (\ n stesso) e il secondo - NULL ASCII (terminatore null). – toriningen

+1

(Spero non ti dispiaccia le modifiche al titolo, sono lì per renderlo più ricercabile.) –

risposta

26

\n è il carattere di nuova riga, mentre \r è il ritorno a capo. Differiscono in ciò che li usa. Windows utilizza \r\n per indicare che è stato premuto il tasto Invio, mentre Linux e Unix utilizzano \n per indicare che è stato premuto il tasto Invio.

Quindi, userei sempre \n perché è usato da tutti; e if (x == '\n') è il modo corretto per testare l'uguaglianza dei caratteri.

13

Il '\ n' è il "Line Feed" e '\ r' è il ritorno a capo. Diversi sistemi operativi consente di gestire le nuove linee in modo diverso, come ad esempio

di Windows

auspica un ritorno a capo per essere combinazione di due caratteri, '\ r \ n'.

Linux \ Unix e Mac OS moderna

Utilizza un singolo '\ n' per una nuova linea.

Mac OS Classic

utilizza un unico '\ r' per una nuova linea.

Fondamentalmente, vorrei utilizzare if (x == '\n') come è attualmente utilizzato da tutti i sistemi operativi moderni.

+0

Mac è diverso a seconda della versione [newline] (http://en.wikipedia.org/wiki/Newline). –

+3

Immagino che intendessi il classico Mac OS per '\ r' newline, dato che il moderno Mac OS X è UNIX e usa '\ n' newline. – toriningen

+0

Siete entrambi corretti, avrei dovuto essere più specifico. – josephthomas

2

Ricorda inoltre che se inserisci 25 caratteri e Invio, il primo getc non verrà restituito finché non saranno stati digitati tutti e 25 i caratteri e si preme Invio. Leggere un carattere nel momento in cui viene digitato richiede un codice specifico della piattaforma. Di conseguenza, potresti star meglio leggendo l'intera riga eseguendo fgets in una stringa, tagliando la nuova riga ed elaborando la linea di input nel suo complesso.

0

L'utilizzo di gets() consente di eseguire il buffer degli exploit di overflow e, conseguentemente, degli eventuali attacchi del codice shell. Dovresti usare fgets() e passare una dimensione del buffer.

+3

Questo dovrebbe essere un commento e non una risposta – Pranjal

0

Esistono diversi livelli di astrazione per rappresentare una nuova riga: il runtime del linguaggio di programmazione, l'editor di testo e il sistema operativo. CR (carriage return) e LF (line feed) sono due caratteri di controllo definiti in ASCII. Un'altra codifica di charator potrebbe anche definire un carattere "nuova linea". Il tasto Invio su qualsiasi tastiera trasmette il significato di "all'inizio della riga successiva". La tastiera decide come mappare il tasto Invio sul relativo charactor o charactor di controllo. Alcune tastiere differiscono anche il tasto Invio e Ritorno - lascia che il tasto Invio sia una nuova riga e il tasto Invio sia il ritorno a capo.In una tastiera ANSI standard, c'è solo il tasto Invio, che è mappato su un carattere di ritorno a capo (13) in ASCII. Quindi questo è il contenuto effettivo che viene inviato al sistema operativo dal dispositivo. Tuttavia, diversi SO decidono di interpretare il tasto Invio in modo diverso. Quindi, in un sistema simile a Unix, qualsiasi ritorno a capo viene tradotto in un carattere di avanzamento riga (10 in ASCII) prima di passare al programma che riceve l'input. E su Windows, un CR viene tradotto in due caratteri: un CR seguito da un LF. Tuttavia, è possibile impostare il flusso di input in modo raw, nel qual caso il programma ottiene ciò che la tastiera effettivamente invia. Ora l'editor entra in gioco. Quando l'editor riceve un CR dallo stdin in modalità raw, sa che il CR corrisponde al tasto Invio sulla tastiera (assunto dalla tastiera) e dovrebbe visualizzare una nuova riga sullo schermo. Nella modalità raw, dovrebbe chiamare la chiamata di sistema write per generare un CR + LF. Se il flusso di output non è nella modalità raw, l'editor di testo deve generare la sequenza specifica del sistema operativo come LF su linux.

Infine, il runtime della lingua può anche interpretare la nuova linea a modo suo. Ad esempio, lo standard C dice: Quando si scrive un file in modalità testo, '\ n' viene tradotto in modo trasparente nella sequenza newline nativa utilizzata dal sistema, che può essere più lungo di un carattere. Durante la lettura in modalità testo, la sequenza nativa newline viene tradotta in "\ n". In modalità binaria, nessuna traduzione viene eseguita e la rappresentazione interna prodotta da '\ n' viene emessa direttamente. Nota che '\ n' e '\ r' sono caratteri specifici della lingua che rappresentano rispettivamente LF e CR che sono popolari nei linguaggi C-like. Ma non tutte le lingue devono usare questa notazione.

Per la seconda domanda, "\ n" è '\ n' seguito da un terminatore '\ 0'. Non c'è modo di inserire un '\ 0' dalla console.

Problemi correlati