1

I want to terminate my input by input, EOF(^Z in windows), and here is the program:

#include<stdio.h>
#include<conio.h>
int main(void)
{
    int c;
    while ((c = getchar()) != EOF)
    {
        if (c == '\t')
        {
            putchar('\\');
            putchar('t');
        }
        else if (c == '\b')
        {
            putchar('\\');
            putchar('b');
        }
        else if (c == '\\')
        {
            putchar('\\');
            putchar('\\');
        }
        else if (c == '\r')
        {
            puts("\\n");
          //  putchar('\n');
        }
        else{
            putchar(c);
        }
    }
    return 0;
}

and here is my input and output: enter image description here So I am asking: why can't I terminate my input by the first ^Z? Otherwise stated, why do I have to type enter to make a new line in order to terminate my input by input at ^Z?

Bruce Dean
  • 2,798
  • 2
  • 18
  • 30
zhenganyi
  • 169
  • 10

2 Answers2

2

See the discussions in:

On Unix, Control-D is (by default) equivalent to Control-Z on Windows.

All point out that the first time you type Control-Z, the input already accumulated in the input is sent to the program (without a newline); there is a non-zero number of characters sent, so it is not yet EOF. The second time, you type the Control-Z at the beginning of the line, and the program gets zero bytes to read, which is interpreted as EOF.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

There's no real reason beyond "that's how it works". You can just press F6 instead though. That will be seen as signaling the end of file, even if it's not preceded by an enter.

The reason you have to press both F6 and enter is fairly simple: there are really two separate pieces of code involved here. The operating system has a small (somewhat crippled) editing routine that lets you enter a line of data. It has code to process back-space and a few things like that, so you can use them when entering data, even though your code doesn't include any editing capability at all. That routine returns a line of text to your program, but only when you've entered what it is programmed to "think of" as a completely line--and that only happens when enter is pressed.

Once that buffer full of data has been read in by the operating system, it's sent to your program. Your program looks at the contents, and when/if it finds the ctrl+Z, it reads that as signaling the end of the file. But, since the end of file processing is done by your program, not the operating system's editing routine, there's no way for it to be senses until you've pressed enter.

If you really don't like this behavior, most operating systems do provide some way to do un-buffered reading. The exact way varies by operating system though. One Windows, you can use _getch. Most Unix-based systems provide roughly the same capabilities in the Curses library (and if you want to use that, there's also at least one free implementation of curses for Windows).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • when I use F6, I also have to make a new line and type ^Z again to terminate my input , it means that the getchar() doesn't get the previous ^Z ,otherwise it will terminate my input...but ,why? – zhenganyi Nov 14 '14 at 02:08
  • @zhenganyi: Just type F6, then carriage return. No need to type ^Z (directly) at all. – Jerry Coffin Nov 14 '14 at 02:13
  • Then I also have to type F6 twice(it is equivalent to type ^Z,I mean) to terminate my input,and I also have to make a newline to terminate it. My question is why can't I just type F6(or ^Z,whatever) at the end of first line once to terminate my input ? or Why can't program terminate my input when it meets ^Z first time? – zhenganyi Nov 14 '14 at 05:23