getchar() doesn't pass EOF and Ctrl+Z doesn't terminate the program on Cygwin

杀马特。学长 韩版系。学妹 提交于 2019-12-02 14:13:30

问题


Here is a simple program, counting strings, symbols and words.

Everything is ok with the computation, using Cygwin.

But while launching, after input values, the program doesn't print nc, nw, nl and wait for entering further values.

Changing EOF to 13 (Enter) doesn't help anyway.

ctrl+Z is useful too: the program is stopping, writing [n]+ Stopped, where 'n' is always different number.

The code is

#include <stdio.h>
#define IN 1
#define OUT 0


int main () {

    char c;
    int state;
    int nc, nw, nl;
    state = OUT;    

    while ((c=getchar()) != EOF) {
        nc++;

        if (c == 'n') 
            nw++;


        if (c == '\n' || c == ' ' || c == '\t') 
            state = OUT;
        else if (state = OUT){
            state = IN;
            nw++;
        }

    }
    printf ("%d %d %d", nc, nl, nw);
}

回答1:


getchar returns int, not char. It has to do this because it can either return a character value or return the special value EOF to indicate the end of the input file. Since EOF has to be different from all values of the char type, it does not have the type char. So you need to define the variable that contains its return value as an int, not as char.

On some platforms, the char type is signed, and the getchar function does not in fact return the character value, but the character value wrapped around to a non-negative value. In practice, what this means is that ASCII characters are unchanged but, on some platforms, non-ASCII characters are transformed to a value between 128 and 255 instead of between -128 and -1. So in general you need to cast the return value of getchar to an char when you use it as a character. On platforms where the char type is unsigned, this doesn't change anything, but on platforms where the char type is signed, it is necessary to avoid character 255 being mistaken as the end of the file.

int c;
…
while ((c = getchar()) != EOF) {
    …
    if (c == 'n') /* ok because 'n' is part of ASCII and thus always positive */
        …
    if ((char)c == some_other_char) /*cast needed in general*/
        …
}

In Cygwin, like in other Unix-like systems, press Ctrl+D at the beginning of a line to signal the end of the input. Under Windows, you need to press Ctrl+Z (under Cygwin, again like in other Unix-like systems, that instead suspends the programs: it's stopped, but can be resumed with the command bg). Neither of these send a control character to the program, they send an end-of-file indication which C's getchar implementation translates to the EOF value.




回答2:


Initialize the variables which you use to count:

  int nc = 0, nw = 0, nl = 0;

When you don't do that they get random values.

Also, your logic for counting words is wrong.

By else if (state = OUT) you probably meant else if (state == OUT).




回答3:


#include <stdio.h>   
#define IN 1  
#define OUT 0
int main()
{
   int c, nl, nw, nc, state; //c is an int not a char        
   state = OUT;
   nl = nw = nc = 0;   // initialize variables to 0
   while ((c = getchar()) != EOF) {
       ++nc;
       if (c == '\n') // if c is a newline character 
           ++nl;     //increment no of lines
       if (c == ' ' || c == '\n' || c == '\t')
           state = OUT;
       else if (state == OUT) // == for comparing
       {
           state = IN;
           ++nw;
       }
    }
   printf("%d %d %d\n", nl, nw, nc);
return 0;
}

Your program is supposed to look like the above one. c is an int and not a char because getchar converts the input to unsigned char and since it cannot hold negative values and since EOF holds -1 , the while loop will never end.

It ends when you press CTRL+Z(in windows else CTRL+D) because pressing it will simulate an EOF in the stdin.




回答4:


You have few bugs here.

int nc, nw, nl;

Should be

int nc = 0, nw = 0, nl = 0;


else if (state = OUT){

I think you meant

else if (state == OUT) {

ENTER is 10 not 13.

getchar() on cygwin returns -1 at the end of file (I don't know why). So you can replace EOF with -1. You can test your program this way: ./program.exe < inputfilename




回答5:


still having this problem? may have found a solution: if you type some characters and press ctrl-z, then that ctrl-z counts as a normal character (code 26), but at the beginning of a line (meaning: you don't type anything but the ctrl-z char) it counts as EOF. so:

while ( (ch=getchar())!=26 ){
    if (ch==EOF) break;
}

this way it doesn't matter where you type the ctrl-z char, the iteration ends.



来源:https://stackoverflow.com/questions/26192479/getchar-doesnt-pass-eof-and-ctrlz-doesnt-terminate-the-program-on-cygwin

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!