5

In section 1.5.2 of the 2nd ed. K&R introduce getchar() and putchar() and give an example of character counting, then line counting, and others throughout the chapter.

Here is the character counting program

#include <stdio.h>
main() {

long nc;

nc = 0;
while (getchar() != EOF)
    ++nc;
printf("%ld\n",nc);
}

where should the input come from? typing into the terminal command window and hitting enter worked for the file copying program but not for this. I am using XCode for Mac.

It seems like the easiest way would be to read a text file with pathway "pathway/folder/read.txt" but I am having trouble with that as well.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
Davis
  • 87
  • 1
  • 5

2 Answers2

9

From the interactive command line, press ctrl-D after a newline, or ctrl-D twice not after newline, to terminate the input. Then the program will see EOF and show you the results.

To pass a file by path, and avoid the interactive part, use the < redirection operator of the shell, ./count_characters < path/to/file.txt.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • Interesting. Is it clear why the return key worked on the first example: – Davis Jun 25 '13 at 23:46
  • 1
    @Davis: After you typed the first line followed by Enter, the program was probably just waiting for more input. Presumably your first program prints output for each line of input as it receives it. Your character counting program doesn't print anything until it's seen *all* the input. – Keith Thompson Jun 25 '13 at 23:48
1

Standard C input functions only start processing what you type in when you press the Enter key IOW.Every key you press adds a character to the system buffer (shell).Then when the line is complete (ie, you press Enter), these characters are moved to C standard buffer. getchar() reads the first character in the buffer, which also removes it from the buffer.Each successive call to getchar() reads and removes the next char, and so on. If you don't read every character that you had typed into the keyboard buffer, but instead enter another line of text, then the next call to getchar() after that will continue reading the characters left over from the previous line; you will usually witness this as the program blowing past your second input. BTW, the newline from the Enter key is also a character and is also stored in the keyboard buffer, so if you have new input to read in you first need to clear out the keyboard buffer.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 2
    It's not a property of C. The shell program is what buffers things by line. To say that `getchar` is line-oriented or that standard C programs have a keyboard buffer is very wrong and misleading. – Potatoswatter Jun 26 '13 at 01:45
  • Thanks for down voting.Now could you explain how `getchar()` reads character on pressing enter key? – haccks Jun 26 '13 at 08:25
  • 2
    It is not the shell that buffers char, it is the tty driver (terminal or console driver if you prefer). These are external to C programs of course. – Jean-Baptiste Yunès Jun 26 '13 at 14:54
  • @Jean-BaptisteYunès;On entering a string,Please explain how `getchar()`reads character on pressing enter key? – haccks Jun 26 '13 at 16:10
  • 2
    Well THIS IS NOT A C problem! `getchar()` really reads input chars one by one. The "problem" is that when you type a string with your keyboard, individual char are not presented to your program as soon as they are typed, they are buffered by the system. This is made to let users erase chars in case of mistyping for example. If not, you would have to take and such chars into account inside your programs. The system usually delivers the chars you typed when you press . You can change this behaviour, in Unix just have a look at your tty config (stty -a), cooked/raw modes. – Jean-Baptiste Yunès Jun 26 '13 at 16:19
  • The buffer that `getchar()` uses is not the buffer that the keyboard fills. – Jean-Baptiste Yunès Jun 27 '13 at 17:23
  • @haccks `getchar()` uses a buffer allocated by the C standard library, usually in the `FILE` object. On a Unix-like system, this is filled by the `read` system call. If `read` returns zero, then `getchar` presumes that the file is finished. `read` simply moves data from some object in another process, identified by `open`, `socket`, or the like, to the buffer in the calling process. `read` returning zero is just a convention; you may still be able to pass data through the descriptor after getting an EOF. (Try it and see with a terminal.) – Potatoswatter Dec 03 '13 at 09:51
  • @Potatoswatter; Hmmm. What I understand now is, correct me if I am wrong, *when characters are typed through keyboard then it goes to keyboard (system) buffer and does not available to program. Om pressing key it goes to C standard buffer and feed to the program (by `read`).*, isn't it? – haccks Dec 03 '13 at 10:38
  • @haccks Correct. It would be more accurate to call the "keyboard buffer" the shell, though. The connection between the shell and the program with `getchar` is just a generic UNIX pipe. – Potatoswatter Dec 03 '13 at 23:26
  • @Potatoswatter; One more thing; What does it mean by line-oriented in case of buffering? – haccks Dec 04 '13 at 06:36
  • @haccks Line orientation means the buffer is flushed after each newline. The flush is initiated by the shell; you can also force it by ctrl-D in which case `read` will return a buffer not terminated by a newline. You can also override the behavior to get keyboard interactivity without pressing return, such as with libcurses. None of this is dictated by the C or C++ standards, which really don't provide for interactivity at all. Major standardization failure. – Potatoswatter Dec 04 '13 at 06:46