web-dev-qa-db-fra.com

Signal EOF dans le terminal mac osx

Je suis perplexe par la question 1.5.2 dans K&R. J'ai cherché sur Google pendant un certain temps et j'ai découvert que je devais fournir l'entrée EOF après avoir entré les caractères.

long nc = 0;

while (getchar() != EOF)
    ++nc;
printf("%ld\n", nc);

return 0;

J'ai essayé à la fois commnad-D et control-D comme EOF entrées mais rien n'a fonctionné. Une idée comment fournir le EOF pour mac osx?

35
Morpheus

Par défaut, les terminaux OS X (anciennement Mac OS X) reconnaissent EOF lorsque Ctrl-D est pressé au début d'une ligne.

En détail, le fonctionnement réel est que, lorsque Ctrl-D est enfoncée, tous les octets du tampon d'entrée du terminal sont envoyés au processus en cours à l'aide du terminal. Au début d'une ligne, aucun octet ne se trouve dans le tampon, donc le processus est informé qu'il n'y a aucun octet disponible, et cela agit comme un indicateur EOF.

Cette procédure sert également de méthode pour fournir une entrée au processus avant la fin d'une ligne: l'utilisateur peut saisir des caractères et appuyer sur Ctrl-D, et les caractères seront envoyés au processus immédiatement, sans attendre normalement que l'on appuie sur entrée/retour. Après cette opération "envoyer tous les octets tamponnés immédiatement", aucun octet n'est laissé dans le tampon. Donc quand Ctrl-D est pressé une deuxième fois, c'est la même chose que le début d'une ligne (aucun octet n'est envoyé, et le processus reçoit zéro octet), et il agit comme un EOF.

Vous pouvez en savoir plus sur le comportement du terminal en utilisant la commande "man 4 tty" dans Terminal. La discipline de ligne par défaut est termios. Vous pouvez en savoir plus sur la discipline de ligne termios en utilisant la commande man termios.

62
Eric Postpischil

Si vous voulez voir ce que EOF est défini comme dans votre terminal, vous pouvez taper

stty all

sur mon mac, cela donne la sortie -

speed 9600 baud; 24 rows; 80 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
-extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
-ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
discard dsusp   eof     eol     eol2    erase   intr    kill    lnext   
^O      ^Y      ^D      <undef> <undef> ^?      ^C      ^U      ^V      
min     quit    reprint start   status  stop    susp    time    werase  
 1       ^\      ^R      ^Q      ^T      ^S      ^Z      0       ^W     

Vous pouvez voir quatre lignes en partant du bas, trois cellules dans eof est ^ D.

Il y a une description plus complète ici qui est où j'ai trouvé l'information.

11
RADan

Je viens de comprendre. Vous devez appuyer sur Ctrl+D+D. Maintenez la commande enfoncée et appuyez sur D deux fois. Je dois dire quelle séquence de touches bizarre.

7
Morpheus