1

When I run the following code and input a sentence I am not given any output. The cursor just goes to a new line.

I copied this straight off the book and double checked it for mistakes (1st edition C programming language by kernighan & ritchie)

#include <stdio.h>
int main()

{
int c,i,nwhite,nother;
int ndigit[10];

nwhite=nother=0;
for(i=0;i<10;++i)
    ndigit[i] = 0;

while (( c=getchar()) != EOF)
    if(c>= '0' && c<= '9')
        ++ndigit[c-'0'];
    else if (c==' ' || c == '\n' || c == '\t')
        ++nwhite;
    else
        ++nother;

printf("digits =");
for( i=0; i<10; ++i)
    printf("%d",ndigit[i]);
printf(", white space = %d, other = %d\n", nwhite,nother);

return 0;
}
  • 3
    `I copied this straight off the book and double checked it for mistakes` I think Kernighan & Ritchie probably indented... – Fiddling Bits Jul 31 '14 at 20:41
  • 1
    "input a sentence I am not given any output." Did you end your sentence with EOF? (OS dependent, but Ctrl+D/Ctrl+Z?) – Kevin L Jul 31 '14 at 20:41
  • getchar is supposed to send EOF automatically after obtaining each character... no? :S – user3689367 Jul 31 '14 at 20:43
  • 1
    @user3689367, no, use `CTRL+Z` – David Ranieri Jul 31 '14 at 20:45
  • i used ctrl+Z and it didnt work, I had to input it like 3times after each other :S – user3689367 Jul 31 '14 at 20:47
  • I have to write my sentence, press enter, input EOF then press enter and it works. How can this make sense?.. why would Kernighan Ritchie give this example without saying to input EOF with ctrl z? – user3689367 Jul 31 '14 at 20:48
  • 1
    Can't you single-step it under an IDE or debugger? I never just dump some code in and expect it to work. – Mike Dunlavey Jul 31 '14 at 20:49
  • @user3689367, because this is OS specific – David Ranieri Jul 31 '14 at 20:50
  • Can you explain this a bit further? I was doing other examples like this which worked without me manually sending EOF...... . long nc; nc = 0; while (getchar() != EOF) ++nc; printf("%d\n", nc); – user3689367 Jul 31 '14 at 20:52
  • it didnt really explain I already knew that. My question is how come the code I have written above exits WHILE without me NOT manually sending EOFs yet here I have to do it? – user3689367 Jul 31 '14 at 21:09
  • Unrelated, but you probably want a space in `printf("%d",ndigit[i]);` or you'll see an output such as "12000320010". – Jongware Jul 31 '14 at 22:14
  • Just FYI you **really should get a newer book**. K&R style of C hasn't been legal (accepted by a Standard-compliant compiler) in several decades. Although I don't see any incompatibilities with this particular example. – Ben Voigt Jul 31 '14 at 22:52
  • I dont have the time to go through C primer plus and its bloody 800 pages – user3689367 Aug 01 '14 at 01:35
  • The program's inteded to be used by taking input from a disk file. Then `EOF` happens once you have consumed all of the file contents (and tried to read beyond the end). – M.M Aug 01 '14 at 03:22

1 Answers1

0

Since you are testing a program copied from another source, I suppose that you don't want to change it, but understanding it.

getchar() obtains exactly 1 character from the standard input, which is a file named stdin in the standard header <stdio.h>.

The standard input, stdin, is considered a file.
Formally speaking, the end-of-file is a "mark" and not a "character".
However, in general, a specific "character" is used to mark the "end-of-file" of a text file.
In Windows the "end-of-file" mark is the character CTRL-Z (whose ASCII code is 26).
In Linxu the mark is CTRL-D (whose ASCII code is 4).

On the other hand, the standard input commonly has the following behaviour:

  • Wait for user enter characters until an Intro/Enter key is pressed.

If the user does not press Enter, then the standard input does not give back the control to the program. This happens even if you enter an "end-of-file" character (say, CTRL-Z).
However, other behaviours are possible.
For example, in Ubuntu console I obtain that CTRL-D is recognized without waiting for the Enter key be pressed.

In any case, you must explicitely type the end-of-file mark in the console of your system.
So, CTRL-Z (perhaps followed by Enter) or CTRL-D have to be pressed for yourself.

ABOUT ENTER and EOF

After Enter is pressed, your program test for EOF, that is, the "end-of-file" mark in your system.
However, the Enter keyword does not prints "end-of-file" marks, but only "end-of-line" ones, which corresponds to the standard character newline '\n'.

Thus, if it is desired that the while() loop terminates after pressing Intro/Enter, the test must be done against '\n', and not EOF.

AN OBSERVATION

It can be observed that getchar() doesn't retrieve the character CTRL-Z, because the ASCII code for CTRL-Z is 26, but getchar() retrieves a negative value (in general -1).
This means that getchar() recognizes the character ASCII 26 as and end-of-file mark, and then it converts to a value with meaning in C, provided by the macro EOF, which is not 26.

What I mean is that EOF is not CTRL-Z, and then one cannot naively send EOF under the assumption that the ASCII 26 (CTRL-Z) will be sent to a text file.

Summarizing, I think that it is important to delucidate the abstract concept of "end-of-file", the role of EOF, and the difference between a "mark" and a "character".
(Another example: in Windows the "mark" for "end-of-line" is the couple of characters CTRL-M CTRL-J, which is not only 1 character, but 2).

Quoted from the standard:

The getchar function returns the next character from the input stream pointed to by stdin. If the stream is at end-of-file, the end-of-file indicator for the stream is set and getchar returns EOF. If a read error occurs, the error indicator for the stream is set and getchar returns EOF.

pablo1977
  • 4,281
  • 1
  • 15
  • 41