You can make a difference in the Apple Support Community!

When you sign up with your Apple Account, you can provide valuable feedback to other community members by upvoting helpful replies and User Tips.

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

how to enter a C EOF character in terminal

I already searched and went to this thread here which has been archieved... http://discussions.apple.com/thread.jspa?messageID=5069197&#5069197

It says EOF can be entered using ctrl-d but that doesn't seem to end the input stream. my code is as follows...

#include<stdio.h>
main()
{
int c;
while((c=getchar())!=EOF)
{
putchar(c);
}
}

any help is appreciated.

PS: Referring to The C programming language, K&R

Message was edited by: AceNeerav

Message was edited by: AceNeerav

MacBook5,1, Mac OS X (10.6.2), iPhone OS 3.1.3

Posted on Mar 9, 2010 3:58 AM

Reply
Question marked as Top-ranking reply

Posted on Mar 9, 2010 10:24 AM

🙂 In C, EOF is a value outside the range of permitted values for a character. It is explicitly not a character. Specifically, ASCII values are 1-byte, while EOF is a value that will not fit in 1-byte, but requires a minimum of 2 bytes. getchar() returns type 'int' rather than type 'char' specifically so that it can signal that the end of stream has been reached.

CONTROL-D does signal the terminal to close the standard input (stdin). However, keep in mind that , by default, the standard input is line-buffered. That means that no data is sent until the buffer is full (about 8K) or until the return key is pressed.

So, in short. Press ctrl-D to signal and end to stdin, and then the enter key to return the buffer.
4 replies
Question marked as Top-ranking reply

Mar 9, 2010 10:24 AM in response to AceNeerav

🙂 In C, EOF is a value outside the range of permitted values for a character. It is explicitly not a character. Specifically, ASCII values are 1-byte, while EOF is a value that will not fit in 1-byte, but requires a minimum of 2 bytes. getchar() returns type 'int' rather than type 'char' specifically so that it can signal that the end of stream has been reached.

CONTROL-D does signal the terminal to close the standard input (stdin). However, keep in mind that , by default, the standard input is line-buffered. That means that no data is sent until the buffer is full (about 8K) or until the return key is pressed.

So, in short. Press ctrl-D to signal and end to stdin, and then the enter key to return the buffer.

Mar 9, 2010 7:31 AM in response to AceNeerav

First, and code you post should be wrapped in


... your code here ...


tags. That will make sure the forum does not see coding syntax as forum formatting meta characters, and it will preserve your indentation.

As the thread you posted suggests, there is no EOF character.

However, at the lowest level the read() system call (somewhere under getchar()), can be told there is no more input, and it will return 0, which somewhere along the way, the getchar() code converts to EOF (where EOF is actually -1).

Depending on what the read() system call is reading, there are different even lower level rules for indicating end-of-file. In your example, you are reading from the Terminal, and the tty driver (NOT the Terminal, but the tty driver) has the convention that if it is in the correct mode, it will tell the read() system call end-of-file when the tty driver sees a specific character.

The normal Unix convention is that Control-D is used to indicate end-of-file. However, this can be changed (but normally it is not), or the tty driver can be put into "RAW" mode which will pass every character entered directly to the reading program and do nothing.

You can see the current terminal driver settings using the

stty all

command. Here are the settings for my Terminal session:

stty all
speed 9600 baud; 13 rows; 145 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

Notice on the 4th from the bottom row, it says 'eof' and below that it says ^D (Control-D). This basically says that the tty driver will tell the read() system call end-of-file when the tty driver sees Control-D.

Control-Z is used for job control, which suspends your current process and allows you to start a different job, optionally putting the current job in the background (Control-Z, jobs, bg and fg commands). Control-Z has nothing to do with end-of-file on a Unix based tty interface.

However, I know that back in the good old days of DOS, a real Control-Z character in a text file WAS the end-of-file indicator. This was bad design even back then. Thankfully, Unix predated DOS and never used that ugly convention.

As to your program, it works for me:

#include<stdio.h>
main()
{
int c;
while((c=getchar())!=EOF)
{
putchar(c);
}
}

I compiled and ran it:

command prompt> gcc example.c -o example
command prompt> example
the quick brown fox jumps over the lazy dog # I typed this
the quick brown fox jumps over the lazy dog # putchar() text
^D # I entered Control-D
command prompt> # the program ends, and I get the command prompt

If you are not seeing this behavior, then I would look closely at your stty settings.

how to enter a C EOF character in terminal

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.