getchar() function bypasses one loop - c

I have this program and I want it to increment by one and print the value of my counter each time I give a character
#include <stdio.h>
int main(void){
//Declarations
long nc;
//Instantiations
nc = 0;
while (getchar() != EOF){
++nc;
printf("%ld\n", nc);
}
return 0;
}
When the loop initiates if I press ENTER I get 1,2,3,4,5... which is ok.But if I type a character or something else it prints the next two numbers 12,34,56,78. Why is that happening??
I am running the program on gcc 4.6.3 Ubuntu 12.04 release.

Terminal input is normally line buffered. Your program only gets input to process when you press ENTER. If you type several characters, you will get one line of output for each character you input (plus the newline itself) as getchar() returns each character in sequence.

Related

getchar() keeps returning EOF value when called second time

I have trouble understanding getchar() and EOF.
I was trying to run this code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char c;
int a = 0; //no. of characters
while (1) {
c = getchar();
if (c == EOF) {
// printf("%i",c);
break;
}
putchar(c);
++a;
}
printf("%i", a);
int b;
while ((b = getchar()) != EOF) {
putchar(b);
}
printf("here"); // to check wether the code written after the loop is executed
}
I terminated the first loop by pressing Ctrl-D twice, I found many posts explaining the reason for this. But whenever I try to call the getchar() function after the first loop it keeps returning EOF, even though that would have been already read by the last call in the first loop.
Code editor - VSCode
OS - macOS
You must define c as an int to accommodate for the full range of possible return values from getchar(), namely all values of type unsigned char and the special negative value EOF (usually defined as (-1)).
On most unix systems, when Ctrl-D is typed in the terminal in canonical mode, whatever input has been buffered by the terminal is sent to the process. In your case, it causes the input to be echoed. If there is no such input pending, the terminal sends zero bytes to the process, which is interpreted by the OS as the end of file. Hitting Ctrl-D twice in a row, or more precisely at the beginning of a read request, does not enter an EOF byte, it signals the end of file to the reading process, hence any further attempt at reading from the stream will return EOF immediately without requesting more user input from the terminal.

C, why does printf add a "D" after a single digit long?

I'm working through the K&R C book and one of the example programs is this:
#include <stdio.h>
int main() {
long nc;
nc = 0;
while (getchar() != EOF) {
++nc;
}
printf("%ld", nc);
return 0;
}
When I run this program, it mostly behaves as I expect. So for an input like This is a sentence, it prints 19.
However, if I input anything under 10 characters (including EOF), there is a capital D appended to the output number.
E.g. for input hello, the output is 6D.
Why is there a D appended to an integer value and what does it mean?
Note: This occurs with cc, gcc and clang.
It turns out that D is part of the ^D that gets printed to the console when I input an EOF (control + D on Unix). Because there is no \n at the start of the printf statement, a single-digit number will overwrite the ^, while a double-digit number will overwrite the entire ^D, which is what gave the impression of some weird behaviour.
What version of gcc are you using? I ran the exact same code using gcc and it runs fine. Maybe it's an artifact left over by your terminal where it's trying to print the Ctrl-D for end of file

How EOF really works in this one?

#include<stdio.h>
#include<conio.h>
int main() {
long nc;
nc = 0;
while (getchar()!= EOF){
++nc;
printf("%ld\n", nc);
}
return 0;
}
My question is: When I input a number or a character, it increments twice >.<
for example: I ran the program, I typed 1, then its going to output
1
2
can someone please tell me why >< cause isn't it suppose to just increment 1? And the value of nc that the program is gonna show is 1? Then its going to become 2 when i enter another number or character?
After entering any number you are pressing Enter key.
and as '\n' != EOF so it is running two times.
int main() {
long nc;
nc = 0;
while (getchar()!= '\n'){ // check for enter key here.
++nc;
printf("%ld\n", nc);
}
return 0;
}
When you input a number and press Enter key, an additional \n character passed to the standard input buffer. getchar reads that number leaving behind \n in the buffer. On next iteration of loop getchar reads \n before pressing any character by you and hence inside while for second time.Hence value is printed twice as \n is not there.
Use below while condition and this shall fix the issue.
while(getchar() != '\n');
This will eat up any number of \n.

Theory Behind getchar() and putchar() Functions

I'm working through "The C Programming Language" by K&R and example 1.5 has stumped me:
#include <stdio.h>
/* copy input to output; 1st version */
int main(int argc, char *argv[])
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;
}
I understand that 'getchar()' takes a character for 'putchar()' to display. However, when I run the program in terminal, why is it that I can pass an entire line of characters for 'putchar()' to display?
Because your terminal is line-buffered. getchar() and putchar() still only work on single characters but the terminal waits with submitting the characters to the program until you've entered a whole line. Then getchar() gets the character from that buffer one-by-one and putchar() displays them one-by-one.
Addition: that the terminal is line-buffered means that it submits input to the program when a newline character is encountered. It is usually more efficient to submit blocks of data instead of one character at a time. It also offers the user a chance to edit the line before pressing enter.
Note: Line buffering can be turned off by disabling canonical mode for the terminal and calling setbuf with NULL on stdin.
Yeah you can actually write whatever you want as long as it's not an EOF char, the keyboard is a special I/O device, it works directly through the BIOS and the characters typed on the keyboard are directly inserted in a buffer this buffer is, in your case read by the primitive getchar(), when typing a sentence you are pushing data to the buffer, and the getchar() function is in an infinite loop, this is why this works.
You can ask me more questions if you want more details about how the IO device work.
Cheers.
Consider the following program,
This program gets the input (getchar runs) till we enter '$' character and prints the output.
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != '$')
putchar(c);
return 0;
}
If we enter input as abcd$$$$$$[Enter], it stores the input in buffer till the last $ symbol. After we pressed enter, the program (while loop) starts to run and getchar function receives one character at a time and prints it, from 'a' till first '$' .
And the program won't end till we press '$' in the input.

How do I enter data in a program to count the entered characters?

I wrote two programs in C to count characters and print the value.
One uses the while loop and the other uses for. No errors are reported while compiling, but neither print anything.
Here's the code using while:
#include <stdio.h>
/* count characters and input using while */
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
And here's the code using for:
#include <stdio.h>
/* count characters and input using for */
main()
{
long nc;
for (nc = 0; getchar() != EOF; ++nc)
;
printf("%ld\n", nc);
}
Both compile and run.
When I type input and hit enter, a blank newline prints. When I hit enter without inputting anything, again a blank newline prints. I think it should at least print zero.
You need to terminate the input to your program (i.e. trigger the EOF test).
You can do this on most unix terminals with Ctrl-D or Ctrl-Z at the start of a new line on most windows command windows.
Alternately you can redirect stdin from a file, e.g.:
myprogram < test.txt
Also, you should give main a return type; implicit int is deprecated.
int main(void)
Your programs will only output after seeing an end of file (EOF). Generate this on UNIX with CTRL-D or on Windows with CTRL-Z.
You wait for an EOF character (end of file) here. This will only happen in two scenarios:
The user presses Ctrl+Break (seems to work on Windows here, but I wouldn't count on this).
The user enters a EOF character (can be done with Ctrl+Z for example).
A better way to do this would be to check for a newline instead.
for your program to work correctly. after you press the enter key, u have to ensure that uyou terminate your loop, so that the program flos correctly. this is done by typing the ctrl+Z from your keyboard. these are the keys that correspond to the EOF.
Pressing Enter on your keyboard, adds the character \n to your input. In order to and the program and have it print out the number of characters you would need to add an 'End of File' (EOF) character.
In order to inject an EOF character, you should press CTRL-D in Unix or CTRL-Z on Windows.
You do realize that newline is a normal character, and not an EOF indicator? EOF would be Ctrl-D or Ctrl-Z on most popular OSes.

Resources