2014-11-30 22 views
10

Con la lettura di this code, sono incappato il printf() dichiarazione seguente:confuso con interessanti printf()

// reset, hide cursor and clear screen 
printf("\e[0m\e[?25l\e[2J"); 

Devo ammettere che io non sono un hacker C pienamente qualificato e non capisco pienamente questo. Mi sono perfezionato, rimuovendo gli argomenti, e ho capito cosa fa (beh, il commento dice tutto), ma non ho idea di come sia fatto. Inoltre, questo è qualcosa di difficile da google per.

Come funziona questa chiamata printf()?

+7

'man 5 termcap' o' man 5 terminfo' – wildplasser

+2

Dalla prospettiva 'printf()' funziona come qualsiasi altra istruzione 'printf()': stampa una sequenza di 'char's nell'output standard. Prova a reindirizzare l'output del programma su un file e poi a controllarne il contenuto. – alk

+0

possibile duplicato di [Ripristina punto dello schermo nella parte superiore dello schermo nella console di Windows e Linux] (http://stackoverflow.com/questions/56324/reset-screen-point-to-the-top-of-screen-in- windows-linux-console) – 2501

risposta

11

Questo in realtà non ha nulla a che fare con printf. Lo standard C11 elenca le sequenze di escape in §5.2.2 e l'elenco è costituito da \a, \b, \f, \n, \r, \t e \v. Come estensione, GCC considera \e una sequenza di escape che corrisponde al carattere ASCII Esc (\E può funzionare anche se il compilatore non supporta nessuno di essi. Consulta la documentazione del compilatore). Quello che segue è non portatile control sequences. Non è garantito che funzionino allo stesso modo su tutti i terminali, o addirittura funzionino affatto. Il modo migliore per sapere è consultare la documentazione del proprio sistema.

§6.4.4.4 descrive anche sequenze di escape ottali. Ad esempio, \033, dove 033 è 27 in decimale e, pertanto, il carattere di escape in ASCII. Allo stesso modo, è possibile utilizzare \x1b, che è una sequenza di escape esadecimale che specifica lo stesso carattere.

Se ispezioniamo l'output del programma con od -c, viene visualizzato 033.

(✿´‿`) ~/test> ./a.out | od -c 
0000000 033 [ 0 m 033 [ ? 2 5 l 033 [ 2 J 
0000016 

Le sequenze di escape ANSI vengono interpretati da emulatori di terminale. C convertirà le sequenze di escape ottale/esadecimale nel carattere ASCII Esc. Il tuo compilatore, come estensione, potrebbe anche convertire \e o \E. Come richiesto, una breve spiegazione di ciò che le sequenze di controllo stanno facendo:

  • [0m: azzera tutte le SGR attributi
  • [?25l: nasconde il cursore
  • [2J: da Wikipedia:

    Cancella parte dello schermo. Se n è 0 (o mancante), deselezionare dal cursore alla fine dello schermo. Se n è 1, deselezionare dal cursore all'inizio della schermata . Se n è 2, chiaro intero schermo ...

+0

Potresti aggiungere una spiegazione più dettagliata di cosa fa esattamente il comando 'printf' nella domanda? –

+1

@Daniel Lì, l'ho modificato. –

7

La chiamata printf() semplicemente emettendo una specifica serie di valori di byte. La "magia" è che quei valori sono speciali nel terminale.

Una serie speciale di byte che inizia con il carattere di "escape" ASCII viene chiamata "sequenza di escape". Questi sono stati inventati per i terminali di dati seriali, dove l'unico mezzo di comunicazione con il terminale era l'invio di valori di byte attraverso la connessione seriale. I caratteri ordinari vengono semplicemente visualizzati sul terminale, ma era preferibile avere un modo per spostare il cursore, cancellare lo schermo, ecc. E la maggior parte dei terminali utilizzava sequenze di escape per questo.

http://en.wikipedia.org/wiki/Escape_sequence

C'era un terminale particolarmente popolare chiamato "VT100", e la maggior parte emulatori di terminale di oggi operano utilizzando le sequenze di escape VT100.

Ancora oggi, le sequenze di escape sono utili. Puoi scrivere un semplice programma C che funzionerà sugli emulatori di terminale in Linux, Mac, Windows, dispositivi mobili, praticamente ovunque. Quando è necessario fare qualcosa di semplice come cancellare lo schermo, è sufficiente stampare la corretta sequenza di escape.