Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to type Ctrl-D twice to mark end-of-file?

Tags:

c

eof

getchar

char **query; 
query = (char**) malloc ( sizeof(char*) );

int f=0;
int i=0,j=0,c;


while((c=getchar())!=EOF)
{      
    if(!isalpha(c))
        continue;

    if(f==1)
        query=(char**) realloc(query,(i+1)*sizeof(char*));

    query[i]=(char*) malloc(sizeof(char));
    query[i][j]=c;
    j++;


    while( (c=getchar())!=EOF&&c!=' '&&c!='\t' )
    {      

        query[i]=(char*) realloc(query[i],(j+1)*sizeof(char));

        query[i][j]=c;
        ++j;
    }   

    query[i][j]='\0';
    printf("%s\n",query[i]);
    if(c==EOF){

        break;
    }   

   ++i;
   f=1;
   j=0;
}

I want the above code snippet to read a line of strings separated by spaces and tabs until ONE EOF but it requires 2 EOFs to end the loop. Also, strings can consist of only alphabetic characters.

I am struggling on about 2 days. Please, give some feedback.

EDIT: Most probably the reason is I hit CTRL+D keys after I write last string not the enter key, but now I hit enter and then CTRL+D, it works as expected. But, how can I change it to finish after I hit CTRL+D once following the last string?

like image 834
mualloc Avatar asked Jan 21 '14 14:01

mualloc


People also ask

How do you end a program with Ctrl-D?

Ctrl + D will cause the stdin file descriptor to return end-of-file. Any input-reading function will reflect this, and you can then exit the program when you reach end-of-file.

Is Ctrl-D end-of-file?

the “end-of-file” (EOF) key combination can be used to quickly log out of any terminal. CTRL-D is also used in programs such as “at” to signal that you have finished typing your commands (the EOF command). key combination is used to stop a process. It can be used to put something in the background temporarily.


2 Answers

On Unix-like systems (at least by default), an end-of-file condition is triggered by typing Ctrl-D at the beginning of a line or by typing Ctrl-D twice if you're not at the beginning of a line.

In the latter case, the last line you read will not have a '\n' at the end of it; you may need to allow for that.

This is specified (rather indirectly) by POSIX / The Open Group Base Specifications Issue 7, in section 11, specifically 11.1.9:

EOF
Special character on input, which is recognized if the ICANON flag is set. When received, all the bytes waiting to be read are immediately passed to the process without waiting for a <newline>, and the EOF is discarded. Thus, if there are no bytes waiting (that is, the EOF occurred at the beginning of a line), a byte count of zero shall be returned from the read(), representing an end-of-file indication. If ICANON is set, the EOF character shall be discarded when processed.

The POSIX read() function indicates an end-of-file (or error) condition to its caller by returning a byte count of zero, indicating that there are no more bytes of data to read. (C's <stdio> is, on POSIX systems, built on top of read() and other POSIX-specific functions.)

EOF (not to be confused with the C EOF macro) is mapped by default to Ctrl-D. Typing the EOF character at the beginning of a line (either at the very beginning of the input or immediately after a newline) triggers an immediate end-of-file condition. Typing the EOF character other than at the beginning of a line causes the previous data on that line to be returned immediately by the next read() call that asks for enough bytes; typing the EOF character again does the same thing, but in that case there are no remaining bytes to be read and an end-of-file condition is triggered. A single EOF character in the middle of a line is discarded (if ICANON is set, which it normally is).

like image 51
Keith Thompson Avatar answered Oct 03 '22 14:10

Keith Thompson


In the off chance that someone sees this that needs the help I've been needing... I had been searching, trying to figure out why I was getting this strange behavior with my while(scanf). Well, it turns out that I had while (scanf("%s\n", string) > 0). The editor I am using (Atom) automatically put a "\n" in my scan, with out me noticing. This took me hours, and luckily someone pointed it out to me.

like image 22
tlochner95 Avatar answered Oct 03 '22 14:10

tlochner95