I've just started programming c and I'm working through The C Programming Language by Brian W.Kernighan and Dennis M.Richie.
One of the first examples is character counting and the following program is given, but when I enter a string no result it printed.
#include <stdio.h>
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n",nc);
}
Why isn't this working?
You have to finish the input. Your program will count characters until EOF is encountered. EOF, in the keyboard, can be sent by pressing Ctrl-Z then ENTER if you are in Windows, or Ctrl-D then ENTER if you are in Linux/OS X.
as an addition to the answers that were mentioned , here's how to make your program show results when pressing Enter
#include <stdio.h>
main()
{
long nc;
nc = 0;
while (getchar() != '\n')
++nc;
printf("%ld\n",nc);
}
getchar() is buffered input. Since it is buffered, The control will wait until you press Enter key from the keyboard.
In your program, you are checking for EOF by doing
while (getchar() != EOF)
On windows, if you want EOF, you have to input a combination of 2 keys. i.e Ctrl+Z.
If you are on LINUX, then EOF is combination of 2 keys Ctrl+D
As said earlier, control will wait at console until you press Enter, so you have to press
Ctrl+Z Enter - on windows.
Ctrl+D Enter - on LINUX.
You have to send EOF to program by pressing CTRL+D (for linux) or CTRL+Z (for Windows) to end the while loop.
Related
Following "The C Programming Language" by Kernighan and Ritchie, I am trying to enter the program described on page 18 (see below).
The only changes I made were to add "int" before "main" and "return 0;" before closing the brackets.
When I run the program in Terminal (Mac OS 10.15) I am prompted to enter an input. After I enter the input I am prompted to enter an input again - the "printf" line is apparently never reached and so the number of characters is never displayed.
Can anyone help me with the reason why EOF is never reached letting the while loop exit? I read some other answers suggesting CTRL + D or CTRL + Z, but I thought this shouldn't require extra input. (I was able to get the loop to exit with CTRL + D).
I have also pasted my code and the terminal window below.
#include <stdio.h>
int main(){
long nc;
nc = 0;
while( getchar() != EOF )
++nc;
printf("%ld\n", nc);
return 0;
}
From pg. 18 of "The C Programming Language
My screenshot
You already have the correct answer: when entering data at the terminal, Ctrl-D is the proper way to indicate "I'm done" to the terminal driver so that it sends an EOF condition to your program (Ctrl-Z on Windows). Ctrl-C breaks out of your program early.
If you ran this program with a redirect from an actual file, it would properly count the characters in the file.
EOF means end of file; newlines are not ends of files. You need to press CTRL+D to give the terminal an EOF signal, that's why you're never exiting your while loop.
If you were to give a file as input instead of through the command line, then you would not need to press CTRL+D
Adding to the two good answers I would stress that EOF does not naturally occur in stdin like in other files, a signal from the user must be sent, as you already stated in your question.
Think about it for a second, your input is a number of characters and in the end you press Enter, so the last character present in stdin is a newline character not EOF. For it to work EOF would have to be inputed, and that is precisely what Ctrl+D for Linux/Mac or Ctrl+Z for Windows, do.
As #DavidC.Rankin correctly pointed out EOF can also occur on stdin through bash piping e.g. echo "count this" | ./count or redirecting e.g. ./count < somefile, where somefile would be a text file with the contents you want to pass to stdin.
By the way Ctrl+C just ends the program, whereas Ctrl+D ends the loop and continues the program execution.
For a single line input from the command line you can use something like:
int c = 0;
while((c = getchar()) != EOF && c != '\n'){
++nc;
}
I am new to C Programming and Ubuntu. I was reading the "The C Programming Language" by D.M Ritchie where I found the following code:
#include <stdio.h>
int main()
{
int c;
int nc=0;
while((c = getchar()) != EOF)
{
nc++;
}
printf("%d Characters \n",nc);
return 0;
}
But while running the program I enter "Hello" ,then CTRL+D twice to get the actual number of characters which is 5.
But when I enter "Hello" then CTRL+D once, nothing happens, the terminal still waits for input.
Why?
Quoting #Veritas's comment,
On linux Ctrl-D only works when the buffer is already empty otherwise it just flushes it. Therefore unless he has pressed enter without any characters after that, he will have to press Ctrl-D twice.
This explains the issue. You have to press it twice because you , after typing Hello, did not press the Enter to flush the input into the stdin. So the first time you press CTRL+D, it flushes the data into the stdin. The second time you press it, EOF is sent.
I'm trying to understand how the terminal driver works in conjunction with getchar. Here are a few sample codes i wrote while reading KandR:
Code 1:
#include <stdio.h>
int main(){
int c = getchar();
putchar(c);
return 0;
}
Code 2:
#include <stdio.h>
int main(){
int c = EOF;
while((c=getchar()) != EOF){
printf("%c",c);
}
return 0;
}
Code 3:
//barebones program that emulates functionality of wc command
#include <stdio.h>
#define IN 1
#define OUT 0
int main(){
//nc= number of characters, ns = number of spaces, bl=number of newlines, nw=number of words
int c = EOF,nc=0,nw=0,ns=0,nl=0, state = OUT;
while((c=getchar())!=EOF){
++nc;
if(c=='\n'){
++nl;
state = OUT;
}
else if(c==' '){
++ns;
state = OUT;
}
else{
if(state == OUT){
state = IN;
++nw;}
}
}
printf("\n%d %d %d %d",nc,nw,ns,nl);
return 0;
}
I wish to understand when the terminal driver actually hands over the input string to the program. Assume my input is the string "this is a test" and i press enter, then here is how the above mentioned codes work:
code 1: outputs "t" (and the program ends)
code 2: outputs "this is a test", jumps to the next line (because it also outputs the enter i pressed) and waits again for input.
code 3: does not output anything for the above string followed by an enter. I need to press Ctrl+D for the output to be displayed (output is 15 4 3 1)
1) Why in case of code 3 do i need to press Ctrl+D (EOF) explicitly for the input to be sent to my program? To put this in other words, why was my input string sent to my program in case of code 1 and code 2 after i pressed enter? Why didn't it also ask for EOF?
2) Also, in case of code 3, if i do not press enter after the input string, i need to press Ctrl+D twice for the output to be displayed. Why is this the case?
EDIT:
For another input say "TESTING^D", here is how the above codes work:
1) outputs "T" and ends
2) outputs "TESTING" and waits for more input
3) ouputs nothing until another Ctrl+D is pressed. then it outputs 7 1 0 0.
In case of this input, the terminal driver sends the input string to the program when Ctrl+D is received in case of code 1 and code 2. Does that mean /n and Ctrl+D are treated the same way i.e. they both serve as a marker for the terminal driver to send the input to the program? Then why i need to press Ctrl+D twice for the second case?
This http://en.wikipedia.org/wiki/End-of-file says that the driver converts Ctrl+D into an EOF when it is on a newline. But in case of my "TESTING^D" input, it works fine even though the ^D is on the same line as the rest of the input. What can be the possible explanation for this?
General information:
In case code 2: you also need to do ctrl+D in order to exit.
In fact EOF is achieved by pressing ctrl+D, so what your while loop condition says:
get input from keyboard
store it in c
if the input was not equal to EOF execute the body of the while loop
EOF is nothing but the integer -1, and this can be achieved in the terminal by pressing ctrl+D. So taking this example:
while((c=getchar()) != EOF){
// execute code
}
printf("loop has exited because you press ctrl+D");
The condition keeps taking input but stops when you press ctrl+D, then it continue to execute the rest of the code.
Answering you questions:
1) Why in case of code 3 do i need to press Ctrl+D (EOF) explicitly
for the input to be sent to my program? To put this in other words,
why was my input string sent to my program in case of code 1 and code
2 after i pressed enter? Why didn't it also ask for EOF?
In code 2 and 3 (Not only 3), you need to press Ctrl+D because the while loop stops taking input from keyboard only when it reads EOF. In code 1 you are not looping, so when you enter one or more character, the program will read the characters entered but will store the first one only, then it will print it and terminate the program, so no need for EOF in that case because you are not asking for it anywhere in any condition.
2) Also, in case of code 3, if i do not press enter after the input
string, i need to press Ctrl+D twice for the output to be displayed.
Why is this the case?
If you started typing when the program is expecting input, then after typing at least one character you press ctrl+D, this will tell the program to stop taking input and return the entered characters. After that, if you press ctrl+D again without entering any character before, this will return EOF which will then not satisfy the condition of the while loop and skip to continue executing the rest of the code
I'm working out of the K&R book, and I'm on the code example of how to count characters from a stream of text. I copied their code and tried running it, but when the command line prompts you for characters, the loop doesn't exit and thus will never print out the character count. Is there an error here I'm not catching?
#include <stdio.h>
main()
{
long nc;
nc = 0;
while(getchar() != EOF) {
++nc;
}
printf("%1d\n", nc);
}
Whenever you want to stop it just send the EOF signal to the shell.
Ctrl+d in Linux or Ctrl+z on Windows.
By the way (as additional info) Ctrl+c send SIGINT to a process in Linux and on Windows it does something similar.
Have you tried to press Ctrl+D (on Linux) or Ctrl+Z (on Windows)? If yes then It will come out of loop for sure. On pressing these keys, it will return EOF and loop will terminate.
Try ending your character stream with CNTL-Z (end of file character). Just hitting Enter results in a CR which is just another character to count
I am reading through "The C Programming Language", and working through all the exercises with CodeBlocks. But I cannot get my character counter to work, despite copying it directly from the book. The code looks like this:
#include <stdio.h>
main(){
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
When I run the program, it opens a window I can type in, but when I hit enter all that happens is it skips down a line and I can keep typing, but I think it's supposed to print the number of characters.
Any idea what's going wrong?
This line:
while (getchar() != EOF)
means that it keeps reading until the end of input — not until the end of a line. (EOF is a special constant meaning "end of file".) You need to end input (probably with Ctrl-D or with Ctrl-Z) to see the total number of characters that were input.
If you want to terminate on EOL (end of line), replace EOF with '\n':
#include <stdio.h>
main(){
long nc;
nc = 0;
while (getchar() != '\n')
++nc;
printf("%ld\n", nc);
}
Enter is not EOF. Depending on your OS, Ctrl-D or Ctrl-Z should act as EOF on standard input.
I ran into the problem tonight, too. Finally found out that Ctrl-D on Linux worked. You build the source file using cc, and start the program and input a word, then press Ctrl-D twice when finished typing. The number that the program countered will be printed just behind the very word you just typed, and the program terminates immediately. Just like this:
The above answer provided by nujabse is correct. But recently coming across this issue myself and researching the answer, I would like to add why.
Using Ctrl+C tells the terminal to send a SIGINT to the current foreground process, which by default translates into terminating the application.
Ctrl+D tells the terminal that it should register a EOF on standard input, which bash interprets as a desire to exit.
What's the difference between ^C and ^D