C : getchar() and putchar() - c

so I've been teaching myself C and I've come across the 'getchar()' and 'putchar()' methods from 'stdio.h'. As I understand it, 'getchar()' takes the most recent character from the text stream and stores it into a variable whilst 'putchar()' takes this variable and prints it to the terminal.
So I've written the following piece of code:
#import<stdio.h>
void main () {
printf("Enter a character and it will be repeated back to you:\n");
int c;
while (c != EOF) {
c = getchar();
printf("You entered : ");
putchar(c);
printf("\n");
}
}
and I expected it to read the keyboard input and print it to the screen one character at a time. As an example, if I were to type "home", the output would be:
You entered : h
You entered : o
You entered : m
You entered : e
but instead i get:
home
You entered : h
You entered : o
You entered : m
You entered : e
The characters are printed as im typing and then repeated afterwards. I'm not quite sure what I'm doing wrong here or if I am doing anything wrong and just don't quite grasp the concept. Can anyone explain whats happening here?

The output you're getting is expected.
Unless you make use of OS-specific functions to change the terminal settings, terminal input is only made available to the application when you enter a full line. The terminal driver buffers lines to allow you to edit before submitting it, and it echoes your input as you're typing it.
Once the line is entered, each call to getchar() retrieves one character from the line (as well as the final newline).
However, there is a bug in your program unrelated to your question. You're testing c before you assign it the first time. Also, the c != EOF test is checking the input from the previous iteration, which already tried to print that input, but you can't print EOF.
A better way to write the loop would be:
while ((c = getchar()) != EOF) {
printf("You entered : ");
putchar(c);
printf("\n");
}
Or if the combined assignment and test is confusing, you can do:
while (1) {
c = getchar();
if (c == EOF) {
break;
}
puts("You entered: ");
putchar(c);
putchar('\n');
}

Related

Usage of EOF in C

Output
Code:
#include<stdio.h>
main()
{
int c;
printf("Enter any charachter!: ");
while((c = getchar()) != EOF) {
putchar(c);
printf("%d\n", (c = getchar()) != EOF);
}
}
I've tried to test out EOF in C and I'm having a difficult time with it. I've wanted to get the value of EOF and found out that it is -1.
I wrote a simple program using getchar() and putchar().
I have added the screenshot of the program and output. Output doesn't make any sense to me.
As you can see I'm trying to get a character and display it using getchar() and putchar(). And I'm trying to print out the value of the condition used in the while loop. To check the EOF I'm deliberately entering -1 as input. putchar() prints out -1 and then the final printf statement confuses me. I enter -1 for getchar() but 1 displayed meaning c is not equal to EOF. But I thought -1 is EOF.
And I don't understand why 11 is also displayed. I'm using codeblocks IDE.
Please help me. Thanks in advance.
EOF isn’t a character, and it isn’t read from the stream. It’s just the return value indicating that there is no more input on that stream. You can signal an EOF by typing CtrlD on *nix or CtrlZ on Windows.
getchar takes input one character(byte) at a time. so when you input '-1' it is treated as a character array input and first getchar takes input only '-' and second one takes input '1'. Thus you are not getting your desired output. Also putchar is designed to print one character at a time. So it might not work properly too. You can change your code following way to make it work.
int c;
while(scanf("%d", &c)!=EOF) { //to ensure there is some input value as scanf will return EOF when input stream finishes.
printf("%d\n", c);
if(c == EOF) {
printf("c is equal to EOF\n");
break;
}
}

how to use fgets to get a number AND CLEAN the stdin afterward, nothing else helped

I am trying to get a single digit number from stdin.
Using scanf("%d",&choice); is not good because if something like 3fjios or fjaifdj is entered then it keeps everything after the digit (if there is one), so if later I have scanf("%s",name); it takes the other chars and messing up. And also using scanf is bad (or so it seems from Google).
After a lot of digging I understand that we should use fgets, to read input into a string and then parse through it.
But! Nowhere is explained how to properly clear the buffer afterwards.
So if I do something like:
char choice[3];
do {
fgets(choice, 3, stdin);
scanf("%*[^\n]");
scanf("%*c");//clear upto newline
} while (choice[1] != '\n');
this works only if I enter a string longer than 2 chars.
When I enter a single char for fgets then the scanf actually waits for another input... which is bad.
The other big problem is if I enter more than 2 chars (a digit and '\n') then the first 2 chars go into choice, the rest are stuck in the buffer. All the approaches to clearing it seems like they require one to build a nuclear power plant first...
Also, what happens if the user enters an infinitely (a really long) long string?
Can you please show a simple way that will allow the user to enter some string of some (unknown) length, and then to properly check if it contains exactly a single digit at the start, followed by '\n'?
Any other input should loop back to get a new input from the user again.
please don't use complex solutions, only standard simple C please.
I can't believe I wasted 6 hours on this supposedly simple technical thing, just getting an input from the user. Solving the actual problem was easier...
Do not use scanf. It is making things overly complicated. Just use getchar to read and discard the line. eg:
int read_input(void) {
int n;
n = getchar();
if( getchar() == '\n' || n == EOF)
return n;
else
do n = getchar(); while ( n != '\n' && n != EOF);
fputs("invalid entry: ", stderr);
return read_input();
}
int main(void) {
int input;
input = read_input();
printf("user entered: %c\n", input);
return EXIT_SUCCESS;
}

Counting the number of characters in input with getchar() method

I am studying C from The C Programming Language. I have tried to make the following code work:
#include <stdio.h>
int main() {
int char_count = 0;
while (getchar() != EOF)
++char_count;
printf("Number of chars are %ld ", char_count);
return 0;
}
I build and run the code. Then, I enter a random word and press enter. I expect to see a number in the next line, but what happens is that cursor moves to the next line. When I enter a new word same thing happens. What am I missing?
Edit: I expect getchar() to return EOF when the program finishes getting the characters of the first word.
When you are pressing enter/return you are generating \n or \r\n based on the whether you are using unix/osx or windows. You are not generation EOF character.
To generate EOF character you need to press ^D on unix/osx or ^Z on windows.
Inputting the EOF character into the command prompt is always tricky. Doing what #Sarvex recommended will do the trick, by using Ctrl+Z on Windows or Ctrl+D on Unix.
One other interesting thing that you can do without making any changes to your code is instead of having your program accept input from the command prompt, you can redirect input to your program from a text file.
If you had a text file named, "data.txt" with the following text in it:
Hello World. How are you doing?
And the name of your program, after compiling the code was charCount. You could do the following:
The output I received was, Number of chars are 31.
If you change the EOF to \n character, it will do the work after pressing the enter key:
int c = 0;
while (((c = getchar()) != '\n') && (c != EOF))
++char_count;
P.S: Improved Using #David Bowling suggestion.

Copy input from user and put it on screen

I have been going through The C Programming Language by Brian W. Kernighan and Dennis M. Ritchie and am at Character Input and Output, specifically on File Copying. The example in the book
#include <stdio.h>
int main(void)
{
int c;
c = getchar();
while (c != EOF)
{
putchar(c);
c = getchar();
}
return 0;
}
works perfectly.
But I decided to put my own spin on things and rewrite it a bit:
#define <stdio.h>
int main(void)
{
int c;
printf("Please enter a digit: ");
c = getchar();
while (c != EOF)
{
printf("The digit entered was: ");
putchar(c);
printf("Please enter a digit: ");
c = getchar();
}
return 0;
}
After compiling and executing, the result of my code is:
Please enter a digit: 9
The digit entered was: 9Please enter a digit: The digit entered was:
Please enter a digit: *cursor is here*
The input should be:
Please enter a digit: 9
The digit entered was: 9
Please enter a digit: *the cursor should be here*
Also, I have a little problem understanding EOF. It would be great if someone could help me with these issues.
Thank you!
Most 'terminals' do not send keyboard input to the program 'one key at at time'. Rather, the terminal will wait for the enter key, and then send all keys pressed (up to that point) to the target program. Hence, the question code suffers from getting newlines \n as input, as well as digits.
The code below throws away all non-digit values (but also allows for the EOF value):
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int c;
do {
c=0;
/* Get user input */
printf("Please enter a digit: ");
while(!isdigit(c) && EOF != c)
c = getchar();
/* Produce output. */
if(c == EOF)
printf("\n");
else
printf("The digit entered was: %c\n", c);
} while (c != EOF);
return 0;
}
Compile the above (Linux GCC example: gcc -Wall -o test *.c)
Then execute: (Linux example: ./test)
Please enter a digit: 5
The digit entered was: 5
Please enter a digit: 6
The digit entered was: 6
Please enter a digit: <CTRL-D>
<CTRL-D> usually generates an EOF condition.
Because the ENTER value "\n" (ASCII value 10) will be get by
getchar(c);
so it will do second time of
printf("The digit entered was: ");
printf("Please enter a digit: ");
Well, it's the trouble about the new-line character that you feed the standard input with while handing your piece into the console screen.
Let me ask you this:
With the code that you have said to work perfectly, you probably have tried some input like "Hello!" let's say, or maybe just a single character like "9" as in your example. You have typed down 'H' then 'e' then 'l' ... then '!' and then hit the enter-key, or just '9' and then hit the enter-key.
After that, you had the following on your screen:
Hello!
Hello!
_
The last underscore there is for indicating the flashing cursor. My question is: Why is it there? Why is it not right next to the last '!'?
Same story with the 9, this would be the things on your screen:
9
9
_
Well, here's why: It is because your programme has printed one more character that you cannot see directly, a new-line character '\n'. Proof: If it hadn't printed that, the underscore would flash next to the '!' or '9'.
When you hit your enter-key, you feed the standard input with a new-line character '\n' in addition to whatever you had typed down so far in that session. Standard input gets fed with all that and getchar(); consumes them one by one.
In your code which doesn't work as you had expected, you feed the standard input with '9' '\n', getchar(); first gets the '9' and then '\n', and then it looks for more, but there isn't any more. Only then (when there isn't more) it asks from you for more.
And that's the story...
To get what you were expecting, you should do something else, I won't tell you that directly, it's a good exercise. I can hint you that you should be using another while loop within the one you already have with a condition checking for a '\n' encounter.
EOF is just a special character, or rather a value indicating a special case of being at the End Of File. For standard input, I guess it can be issued with the CTRL + D key combination on Linux, it is CTRL + Z on Windows. Using that combination and then hitting enter should get you out of that outer loop.
You're being tripped up by a trailing newline in your input; when you type 9 and hit Enter, the input stream that your code reads from will contain the encodings for two characters, the 9 and a newline (in ASCII, it would be the sequence of values [57,10]) . Here's how it breaks down:
Code prompts you to enter a digit
You type 9 and hit Enter
Input stream now contains the characters {'9', '\n'};
getchar returns the next available character from the input stream, which is '9'
'9' is not equal to EOF, so you print the digit and prompt for the next character
getchar returns the next available character from the input stream, which is '\n'
'\n' is not equal to EOF, so you print the character and prompt for the next character
The input stream is now empty, so getchar blocks until you type something else.
You can fix this relatively easily:
#include <ctype.h>
...
while (c != EOF)
{
printf("The digit entered was: ");
putchar(c);
printf("Please enter a digit: ");
do
{
c = getchar();
} while ( isspace( c ));
}
That last little do loop will read characters from the input stream until it sees something that isn't a newline or other whitespace character. You can add an additional check to make sure the character entered really was a digit [0-9]:
while (c != EOF)
{
printf("The digit entered was: ");
putchar(c);
do
{
printf("Please enter a digit: ");
do
{
c = getchar();
} while ( isspace( c ));
if ( !isdigit( c ))
printf( "%c is not a digit!\n" );
} while ( !isdigit( c ));
}
Now, something to be aware of; what you're storing in c is not the value 9, but the encoding for the character '9', which in ASCII is the integer value 57. If you want to store the value 9 in c, you'll have to do something different.

difference between ((c=getchar())!=EOF) and ((c=getchar())!='~'),'~' can be any character

As soon as '~' is encountered, anything after that is not printed and control comes out
while loop
while((c = getchar()) != '~')
{
putchar(c);
printf(" ");
}
input: asdf~jkl
output: a s d f //control is out of while loop
as soon as '^Z' is encountered, anything after that is not printed but control doesn't come out of while loop
while((c = getchar()) != EOF)
{
putchar(c);
printf(" ");
}
input: asdf^Zjkl
output a s d f -> //control is still inside while loop
Please explain why is this happening?
As soon as EOF is encountered, while loop must exit, but this is not happening.
Is is necessary that (ctrl+Z) must be the first character on the new line to terminate while loop?
This has something to do with the working of getchar() and EOF (ctr+Z)
It's the way the console input editor works in a Windows/DOS command prompt. Input is done line by line, which is why you can go back and forth editing the characters until you press ENTER, and at that point the contents of the line are sent to the program and a new line is started.
Whoever wrote the editor in DOS decided that typing ^Z at the beginning of the line was the way to tell the editor that you're done providing input.
The thing is that EOF (end of file) is a virtual mark and not always a real character. Its actual value (-1) suggests that by being way outside the range of character codes (which is also why it's important to use an int variable instead of a char when calling getchar() and fgetc()).
In fact, your example...
while((c = getchar()) != EOF)
{
putchar(c);
printf(" ");
}
...can work as you expect it if you run the program using input redirection ("program.exe < input.txt") to feed it a file with ^Z in the middle. In that case, there is no command line editor in the way.

Resources