问题
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