EOF in C doesnt work - c

I have a problem with reading chars from input. Program should end when I press ENTER or CTRL + Z.
Example input:
LoreCTRL+Z .... is cycling
but when I press CTRL+Z and there is no text before it, it works.
Could anybody help me? Thanks
int intFromConsole = getchar();
if((intFromConsole == EOF) || (intFromConsole == '\n')){
//code
}

That is probably not related to your program but to the terminal subsystem (in the kernel) which is responsible for that behaviour.
Your terminal is usually in "line discipline" state. Notice that your program doesn't receive the "Lore" directly but only when you press return. (the input is line-buffered).
Another catch, you usually shouldn't expect Ctrl+Z (ASCII 26) as input since that is intercepted by the terminal subsystem in most terminal states, which pauses your program and sends it to the background.
You can get more interesting information from Linus Akesson's article The TTY demystified.

The function getchar() uses buffered input. In Windows, Ctrl-Z is only recognised when it follows a newline entry. But in Windows, you might have conio.h available to you in the library. If so, here is something for you to experiment with. It accepts each keystroke immediately, and prints the value in hex. It exits when Ctrl-Z is pressed.
#include <stdio.h>
#include <conio.h>
#define ENDOF 0x1A // Ctrl-Z
int main(void) {
int ch;
do {
ch = _getch();
printf("%02X\n", ch);
} while(ch != ENDOF);
}
Program input
1234<Ctrl-Z>
Program output
31
32
33
34
1A

Program should end when I press ENTER or CTRL + Z.
If above is what you want, you could do something like :
int main(void)
{
char ch;
do
{
while(ch!='\n')
getchar(); // waste the buffer
/* Do the useful stuff here */
ch=getchar();
}while(ch!=EOF && ch!='\n');
/* Note the logical operator is && . It says if the key pressed
* is neither Enter nor Ctrl -Z do some stuff.
* The program exits only when you directly press Enter key or
* Ctrl -Z / Ctrl -D. Okay ! Now it is time to take a nice walk
* thru the Grand Central Park.
*/
return 0;
}
For Linux machines Ctrl-Z generates the SIGSTOP which cannot be trapped. So to signal EOF you should instead use Ctrl-D.
References :
Linux Signals

Related

How backspace can actually delete the string in getchar() loop

#include <stdio.h>
#include <conio.h>
#define ENTER_KEY '\n'
#define NULL_TERMINATOR '\0'
int main()
{
char name[100], input;
int counter = 0;
while(input != ENTER_KEY)
{
input = getchar();
name[counter] = input;
counter++;
}
counter--;
name[counter] = NULL_TERMINATOR;
printf("%s", name);
return 0;
}
If I write something, it should continuously saved in the name Array. And the counter should go up on every character I enter. But if I press Backspace, it looks like it makes the counter decreased. Because for example if I write "abcdef" and press backspace 3 times and change that to "abcxyz", and then press Enter. It prints "abcxyz".
It depends on the console driver. On most systems (at least Unix-like in line mode and in Windows console), the program does not receive the characters at the moment they are typed but the system prepares a line (up to the newline character) and sends the full line to the program.
In that case, the backspace if often used to edit that console buffer, meaning that the characters erased are actually removed before being handed to the program. So if you type abcdef<backspace><backspace><backspace>xyz<Return> the program will receive the following string: "abcxyz\n".
Beware, in a GUI program or in fullscreen text mode program like emacs or vi, the system is in raw mode (Unix language) and each character is received when it is typed. In that case, the program has to manage the input and erase its own character array when it receives a <backspace>.

Why do I need to press CTRL+D twice to break out of `while ((c=getchar())!=EOF)` in Ubuntu 14.10?

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.

getchar buffered input, EOF and terminal driver

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

K&R C Counting Characters

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

count the number of lines, words, and characters within an input

Right now I am going through a book on C and have come across an example in the book which I cannot get to work.
#include <stdio.h>
#define IN 1
#define OUT 0
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == '\n')
++nl;
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}
It's supposed to count the number of lines, words, and characters within an input. However, when I run it in the terminal it appears to do nothing. Am I missing something or is there a problem with this code?
The program only terminates when the input ends (getchar returns EOF). When running on terminal, this normally never happens and because of this it seems that the program is stuck. You need to close the input manually by pressing Ctrl+D (possibly twice) on Linux or pressing F6 and Enter at the beginning of the line on Windows (different systems may use different means for this).
It's waiting for input on stdin. Either redirect a file into it (myprog < test.txt) or type out the data and hit Ctrl-D (*nix) or Ctrl-Z (Windows).
When you run it, you need to type in your text, press return, then type Ctrl-d and return (nothing else on the line) to signify end-of-file. Seems to work fine with my simple test.
What it is doing is entering a loop for input. If you enter a character or newline, nothing happens on the screen. You need to interrupt the process (on my Mac this is CTRL+D) which serves as EOF. Then, you will get the result.
getchar() returns the input from the standard input. Start typing the text for which you want to have the word count and line count. Your input terminates when EOF is reached, which you do by hitting CTRL D.
CTRL D in this case acts as an End Of Transmission character.
cheers
I usually handle this kind of input like this (for Linux):
1. make a file (for example, named "input.txt"), type your input and save
2. use a pipe to send the text to your application (here assume your application named "a.out" and in the current directory):
cat input.txt | ./a.out
you'll see the program running correctly.

Resources