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
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'm working on character K&R C book to try to learn the C language. I'm having a lot of issues because I'm using windows 10 OS instead of Linux. I'm using msys2 to compile and run my code. I for the longest time couldn't figure out the File copying from section 1.5.1 until asking for help from an expert in the field. He pointed out that I needed to use fflush(stdout);
{
while ((c = getchar()) != EOF) { // read buffer store in c, then check if it is EOF(ctrl+z on windows)
fflush(stdout); //flush buffer
putchar(c); // print the character retrieved
printf("%d\n",(c));
}
return(0);
}
Adding that made my program work as expected. However, Now I'm running into similar difficulty on the character counter of the next section.
long counter = 0; // initialize c variable
while (getchar() != EOF) { //check if character received is EOF(ctrl+z on windows)
fflush(stdout); //flush buffer
++counter; // incrementcounter
}
fflush(stdout);
printf("%ld\n",(counter));
return(0);
I never see the print on my counter at the end.
The attached image shows what happens when I run the file. The "Stopped" print is from when I sent EOF(ctr+Z).
I essentially have two questions:
What exactly happens when I send EOF to my kernel.
Is there a way to send EOF without immediately killing my program?
I hope that was easy to follow and thank you all in advance.
What exactly happens when i send EOF to my kernel.
The system (MSYS) tells the program that its standard input has reached EOF (end-of-file), and there'll be no more input availablr.
Is there a way to send EOF without immediately killing my program?
No. Sending an EOF never terminates a program immediately. It lets the program continue without reading input anymore. It's your program that terminates itself when it found nothing to read.
The reason you see Stopped is that you didn't send an EOF at all! Oj Unix shells (including MSYS and Cygwin), Ctrl-Z means Suspend. You can type fg to bring it to foreground again, then press Ctrl-D to send it an EOF.
Note: Ctrl-Z sends EOF only in Windows CMD, and in Windows 10 you have to uncheck a box.
Simple c program to accept and print the character.
int c;
while((c=getchar())!=EOF)
{
putchar(c);
}
I am not getting why it accept input when I press Ctrl+Z at the end of line
ex Hello(press Ctrl+Z)
hello (some symbol)
but it work properly after leaving a line then pressing Ctrl+Z.
And I am using Window 7
When you call getchar() it in turn ends up making a read() system call. The read() will block until it has some characters available. The terminal driver only makes characters available when you press the return key or the key signifying end of input. At least that is what it looks like. In reality, it's more involved.
On the assumption that by ctrl-Z you mean whatever keystroke combination means "end of input", the reason is the way that the read() system call works. The ctrl-D (it's ctrl-D on most Unixes) character doesn't mean "end of input", it means "send the current pending input to the application".
When you've typed something in before pressing ctrl-D, that input gets sent to the application which is probably blocked on the read() system call. read() fills a buffer with the input and returns the number of bytes it put in the buffer.
When you press ctrl-D without any input pending (i.e. the last thing you didwas hit return or ctrl-D, the same thing happens but there are no characters, so read() returns 0. read() returning 0 is the convention for end of input. When getchar() sees this, it returns EOF to the calling program.
This answer in Stack Exchange puts it a bit more clearly
https://unix.stackexchange.com/a/177662/6555
You have not said what system you are working on, [U|Li]nix or Windows. This answer is Windows specific. For [Li|U]nix, replace references to ctrl-z with ctrl-d.
While using a terminal, Ctrl-z will not produce an EOF (-1) (see good answers from Haccks & JeremyP for detailed whys), so the loop will not exit the way you have it written. However, you can put a test for ctrl-z in your while loop condition to exit...
int main ()
{
int c=0;
puts ("Enter text. ctrl-z to exit:");
while(c != 26) //(26 is the ASCII value for ctrl-z)
{
putchar(c);
c = getchar();
}
return 0;
}
By the way, here is a table showing the values for ASCII control characters.
I found the answer on wiki:
In Microsoft's DOS and Windows (and in CP/M and many DEC operating systems), reading from the terminal will never produce an EOF. Instead, programs recognize that the source is a terminal (or other "character device") and interpret a given reserved character or sequence as an end-of-file indicator; most commonly this is an ASCII Control-Z, code 26.
#include <stdio.h>
int main()
{
int c;
while((c=getchar())!=26)
{
putchar(c);
}
}
You can use ASCII value of CTRL-Z.Now it won't take input after pressing CTRL-Z.
getchar() fution read single character by Pressing Ctrl+Z sends the TSTP signal to your process, means terminate the process (unix/linux)
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.
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