getchar and buffer, EOF [duplicate] - c

I am currently reading K&R's book and typing in the examples from the first section, and there are a couple of examples such as this:
while((c = getchar()) != EOF) {
//do something
}
I am testing these examples on a Windows box and thus running the compiled exe files from the cmd prompt.
To test the example above, how do I simulate an EOF? That is, basically how can I make the loop stop when testing the example from the command prompt?

To enter an EOF, use:
^Z (CtrlZ) in Windows
^D on Unix-like systems

Refer EOF
Windows: Ctrl+Z
Unix :Ctrl+D

First, press: Ctrl^X, next: Ctrl^D

You can also simulate EOF by explicitly giving int variable a value of -1.
Check out this code for more clarity:
#include<stdio.h>
int main() {
// char ch=getchar()
// int ch=-1;
if(ch==EOF) { printf("\nEOF: %d",EOF); }
if((ch!=EOF)==0) { printf("\nit is equal to 0"); }
if((ch!=EOF)==1) { printf("\nit is equal to 1"); }
else { printf("\n it is equal to other value"); }
system("pause");
return 0;
}

I had the same problem after pressing Ctrl+d program stopped and returned 0.
If you use Clion press Ctrl+Shift+a than type Registry press enter and make sure run.processes.with.pty. is unchecked.
After that compile program again and then you can type in input but don't press Ctrl+d on the same line as input it will return 0 or Error.

Related

Why I can't reach stdin at startup on Raspberry-Pi Jessie Lite?

I have this code. what I want to do is to wait for user to press 'q' to end the program.
.
...starting few threads, which use fflush(stdout) (just saying...)
.
char n = 0;
while (n != 'q') {
n = getchar(); //tried to use scanf() here as well
printf("%c", n);
}
...killing all threads...
return 0;
When I run this in a normal Linux enviroment it works fine.
The problem starts when I run this program at startup on my raspberry-pi with debian jessie lite distribution (I added the path to the program to /etc/rc.local) - it ends in an infinite loop, scanf is still returning -1 and getchar() some weird character and the program won't end, when I press q. Ctrl+C doesn't work either so there is no way, how to end the program.
Any suggestions? (at least how to kill the program...?)
Edit: To let you know what the program does.
Raspberry-pi with this program is attached to some serial ports and converts and transfers some GPS data. It should work "out of the box" without any keyboard or mouse or monitor. = Just plug the device to some cables and do nothing more. In some cases someone would like to see log files on the raspberry, so he needs to stop the program, obviously.
Edit2: when I did the same with some normal Raspbian, it worked fine too.
Update:
I tried to debug it - shrinked the code to this only
int main(void){
char n=0;
int x;
while (n != 'q'){
clearerr(stdin);
x=scanf("%c",&n);
printf("%c %d\n",n,x);
}
return 0;
}
added service start udev to rc.local and tried command update.rc.d udev enable
output on raspberry-pi when launched at startup is still
-1
-1
-1
.
.
so there definitely have to be something wrong with stdin.
After startup and on other systems, the output is obviously q 1 (when I press 'q' (and enter) ...)
when I tried to read from /dev/tty, fopen() returned NULL
Really need a help with this
The idiomatic way to write this loop is:
int c;
while ((c = getchar()) != EOF && c != 'q'){
putchar(c);
}
Your implementation cannot detect end of file and will loop forever, printing funny characters such as ΓΏ.
Just a wild guess that stdin maybe redirected to something else and you need to read from keyboard directly. try the following code:
FILE *tty = fopen("/dev/tty", "r");
if (!tty) {
exit(1);
}
int n=0;
while (n != 'q'){
n=fgetc(tty); //tried to use scanf() here as well
printf("%c",(char)n);
}

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

count blanks from the input

I wrote a program to count blanks. I can compile it and run it, it's fine. But why it does not display the count?
#include<stdio.h>
main()
{
int count=0;
int c;
while((c=getchar())!=EOF)
{
if(c == ' ') count++;
}
printf("%d\n",count);
}
Your exact code (errors and all) works as you'd expect at ideone.
How do you terminate the input? To send an EOF signal to your program from the console type, at the beginning of a line, CtrlD in Linux or CtrlZ in Windows.
Also try to run with redirected input. Something like
yourprog < data.txt
or
echo one two three four | yourprog
You're probably not getting the EOF that you expect from input. You may be expecting the Enter key to be EOF, which will not happen. Have you tried using one of the ctrl+ combinations such as Z or D (depending on OS) to send the EOF ?

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.

How to simulate an EOF?

I am currently reading K&R's book and typing in the examples from the first section, and there are a couple of examples such as this:
while((c = getchar()) != EOF) {
//do something
}
I am testing these examples on a Windows box and thus running the compiled exe files from the cmd prompt.
To test the example above, how do I simulate an EOF? That is, basically how can I make the loop stop when testing the example from the command prompt?
To enter an EOF, use:
^Z (CtrlZ) in Windows
^D on Unix-like systems
Refer EOF
Windows: Ctrl+Z
Unix :Ctrl+D
First, press: Ctrl^X, next: Ctrl^D
You can also simulate EOF by explicitly giving int variable a value of -1.
Check out this code for more clarity:
#include<stdio.h>
int main() {
// char ch=getchar()
// int ch=-1;
if(ch==EOF) { printf("\nEOF: %d",EOF); }
if((ch!=EOF)==0) { printf("\nit is equal to 0"); }
if((ch!=EOF)==1) { printf("\nit is equal to 1"); }
else { printf("\n it is equal to other value"); }
system("pause");
return 0;
}
I had the same problem after pressing Ctrl+d program stopped and returned 0.
If you use Clion press Ctrl+Shift+a than type Registry press enter and make sure run.processes.with.pty. is unchecked.
After that compile program again and then you can type in input but don't press Ctrl+d on the same line as input it will return 0 or Error.

Resources