This question already has answers here:
while ((c = getchar()) != EOF) Not terminating
(9 answers)
Closed 3 years ago.
I'm a beginner programmer (forgive this very basic question), and I am learning C through the Kernighan and Ritchie book "The C programming language".
I copied this program from the book, and it compiles fine, but when an input is given, the program does nothing.
#include <stdio.h>
int main() {
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%1d\n", nc);
}
The output is supposed to be the number of characters in the input, but nothing is happening
It will print the number of inputted characters when it has encountered the EOF (=end of file) condition.
If you're providing input through a terminal, there's no natural end of file
so you need to signal it with a special keyboard shortcut, which is typically either Ctrl+Z on Windows and Ctrl+D on a Unix system (Linux, MacOs, ...). (Windows also appears to require that you type an Enter both before and after the Ctrl+Z. The new-line character before the Ctrl+Z counts as another character, which effectively means that Windows, unlike Unixes, doesn't appear to allow you to have text-files that don't end with a new-line, at least with mingw gcc without cygwin.)
If you provide the input file through redirection as in ./a.out < some_file, then you don't have to worry about that because filesystem files have natural ends.
You are supposed to end the stream with an EOF indicator, which is CTRL+Z on Windows and CTRL+D on Linux based Operating systems. When getchar() reads EOF, it exists the while loop and the number of characters is output to stdout.
Related
I am doing Kernighan/Ritchie ANSI C Second Edition exercises in the first chapter. Problem is, the book didn't teach you yet about argv/argc or fopen, yet it uses such a structure where if you just run your program and give input at runtime, you will get into an infinite repetition of the test (c = getchar()) != EOF because getchar() at runtime will prompt the user for input as soon stdin is empty, and when the user gives input, the input will process, and getchar() will prompt for another input. EOF will literally never get encountered.
My mentors told me that you can input an EOF with ctrl+d, but that is obviously a hack and not intended.
Another solution they gave me is a.out <<< "some string" which actually works and does have EOF, but now I am at a point where I have to have an input of multiple lines, and I have no idea how to input lines like this, and frankly I heard that <<< didn't even exist in 1989.
Here is a code example of the type of problem:
#include <stdio.h>
/* count characters in input; 1st version */
int main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
So how did programmers feed input in this kind of program back in the day? Mind you, you are only allowed to use the things the book taught you until now (which is literally nothing about input)
I am working on the infamous book "Prentice Hall Software Series" and trying out the Code they write and modifying it to learn more about C.
I am working with VIM on Fedora 25 in the console. The following code is a quote from the book, I know "int" is missing as well as argc and argv etc.
Kernighan and Ritchie - The C Programming Language: Page 20
#include <stdio.h>
/* copy input to output; 1st version */
main(){
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
With this code I couldn't manage to get the "EOF" to work. I am not sure if "ctr + z" really is the real thing to do, since it quits any console program in console.
Well since I was unsure i changed the condition to
...
while (c != 'a') {
...
So normally if I enter 'a' the while condition should break and the programm should terminate. Well it does not when I try to run it and enter 'a'. What is the problem here?
Thank you guys!
There's nothing wrong with the code (except the archaic declaration of main).
Usually, on Unixes end of file is signalled to the program by ctrl-D. If you hit ctrl-D either straight away or after hitting new-line, your program will read EOF.
However, the above short explanation hides a lot of subtleties.
In Unix, terminal input can operate in one of two modes (called IIRC raw and cooked). In cooked mode - the default - the OS will buffer input from the terminal until it either reads a new line or a ctrl-D character. It then sends the buffered input to your program.
Ultimately, your program will use the read system call to read the input. read will return the number of characters read but normally will block until it has some characters to read. getchar then passes them one by one to its caller. So getchar will block until a whole line of text has been received before it processes any of the characters in that line. (This is why it still didn't work when you used a).
By convention, the read system call returns 0 when it gets end of file. This is how getchar knows to return EOF to the caller. ctrl-D has the effect of forcing read to read and empty buffer (if it is sent immediately after a new line) which makes it look to getchar like it's reached EOF even though nobody has closed the input stream. This is why ctrl-D works if it is pressed straight after new line but not if it is pressed after entering some characters.
This question already has answers here:
Why doesn't getchar() recognise return as EOF on the console?
(8 answers)
Closed 8 years ago.
I am a complete beginner in C, so sorry if this question sounds too trivial.
My understanding of getchar() and putchar() is that they process text streams one character at a time. Let's say I have this program that takes textual input from the user and displays it on the screen:
#include <stdio.h>
main(){
int c;
c = getchar();
while(c!= EOF){
putchar(c);
c=getchar();
}
}
Here's what I think is happening:
Suppose I run this program and I enter the word Hi. getchar reads the first character (namely H) and stores it in c. Then the program enters the while loop and puts H to the screen. Then it gets the next character (i) and prints it. Then comes the EOF and when getchar assigns the value to c, the while loop ends. So, according to this interpretation of what has happened, the program should end after printing all the characters and having reached the end of file.
When I run the program, however, after printing the string, the program waits to receive additional input, meaning it doesn't end, rather waits for the user to input more text streams.
Why does this happen and where do I get it wrong?
When you typed Hi and ENTER, no EOF is automatically inserted.
Instead, you need to press certain keys to generate EOF. On Unix system, press Ctrl + D, on Windows, press Ctrl + Z.
so I built a very basic program according to The C Programming Language book, but when I run it, it keeps asking input after I enter one, the loop should ended when there are no inputs longer right? or Am I wrong? srry for my bad english
int main()
{
long nc;
nc = 0;
while ( getchar() != EOF) {
++nc;
}
printf("%ld\n", nc);
}
Your loop is expecting an EOF character to terminate, not just an empty string. *nix consoles typically translate a Ctrl-D on an empty line as EOF, in Windows I believe it's Ctrl-Z but I could be wrong.
No.
For standard input, you must input EOF manually. It's Ctrl+Z in Windows and Ctrl+D in Linux.
If you are using Linux and redirect standard input from file. It will end.
This will keep reading input until it gets to an end-of-file. If you're reading from the terminal (you haven't redirected the program to read from a file), it will only get an EOF if you explicitly give it one. How you do that dpends on your OS, but on most UNIX-like systems, you can generate an explicit eof by hitting ctrl-D
You can press the Ctrl + D to input EOF, anything other keyboard can't! So if you want to interrupt the loop, you must input the EOF.
Ok I'm just learning C and stumble upon this practice code to count character K&R's book:
#include <stdio.h>
/* count characters in input; 2nd version */
main()
{
double nc;
for (nc = 0; getchar() != EOF; ++nc)
;
printf("%.0f\n", nc);
}
The problem is I don't know whether is it suppose to print the amount of characters or not when I entered any character because there is no output whatsoever, just whitespace (getchar() waiting for another input).
Can someone explain to me what is going on? I'm practicing in bash using vim in openSUSE 11.3.
You have to send the EOF signal/character to the program. If you are running it from inside a terminal window, press Ctrl+D.
If you are piping from a file, like so:
./my_program < input_file_name
then it will work automagically.
Since it is checking for EOF, hit Ctrl-D in the terminal.
As others have mentioned, you have to press control-d (aka ^d) but that only works after you hit return. In other words you cannot type "foocontrol-d" and expect it to work. "fooreturncontrol-d" would work, though.
Also please note that K&R is a fine fine book, but was written decades ago. The counting algorithm presented only work on ASCII-ish input. Wide characters (UTF-8, etc) would not be counted correctly.
Also also note, the example you quoted is using a floating point number for this counting. There is little strictly wrong with this, but for speed and efficiency, most people would use unsigned ints, longs, or some other intergral datatype. You are not likely to be reading ¾th of a character!