I'm reading K&R's The C Programming Language and have become confused on putchar and getchar. I made a program where you enter 10 chars and the program prints them back out to the screen.
#include <stdio.h>
int main()
{
int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
putchar(ch);
}
return 0;
}
I expected to get an output like this:
Enter a single character >> a
a
Enter a single character >> b
b
...and so on 10 times but this is the output I got: (I stopped after entering 2 chars)
Enter a single character >> a
aEnter a single character >>
Enter a single character >> b
bEnter a single character >>
Enter a single character >>
not sure why my input character is being combined with the fixed string and being output.
Also, I'm not too sure why ints are used to store characters.
putchar(ch);
just prints single character and the following printf continues within the same line. Simply add:
putchar('\n');
right after putchar(ch);, which will explicitly start the new line before the printf is executed. Additionally you should also take '\n' from the input which stays there after you enter the character:
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
getchar(); // <-- "eat" new-line character
putchar(ch);
putchar('\n'); // <-- start new line
}
You are not printing a new line. After putchar(ch); you should use putchar('\n'); to print a new line.
User terminal can operate in canonical and non-canonical modes. By default it operates in canonical mode and this means that standard input is available to a program line-by-line (not symbol-by-symbol). In question user inputs something (let it be letter 'a', 0x61 in hex) and pushes enter (new line character '0x0A' in hex). Ascii table is here. So this action gives a two symbols to a program. As mentioned in man getchar() reads it symbol-by-symbol. So loop iterates twice for one character. To see what is going on use the following program (+loop counter output, +character code output):
#include <stdio.h>
#include <unistd.h>
int main()
{
int i;
char ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character %d >>", i);
ch = getchar();
printf("Ch=0x%08X\n", ch);
/*putchar(ch);*/
}
return 0;
}
Output:
┌─(02:01:16)─(michael#lorry)─(~/tmp/getchar)
└─► gcc -o main main.c; ./main
Enter a single character 0 >>a
Ch=0x00000061
Enter a single character 1 >>Ch=0x0000000A
Enter a single character 2 >>b
Ch=0x00000062
Enter a single character 3 >>Ch=0x0000000A
Enter a single character 4 >>^C
So program gets two symbols and prints them. And new line symbol is not visible. So in the question user see one strange additional line.
Detailed description on different terminal modes and how to make its adjustments can be found here.
Also stty utility can be useful while working with terminal options ("icanon" tells if terminal use canonical mode or not).
And about storing chars as int in getchar() output - see my answer for similar topic.
The term on which our focus should be on, is "Stream".
A "Stream" is a like a bridge, responsible for flow of data in a sequential way. (The harmony of smooth streaming, both in and out of a program, is managed by libraries/header files, e.g. stdio.h)
Coming back to your question :
When you type input as 'a' and hit 'enter', you supply 2 values to input stream.
- a (ASCII Value : 97)
- enter (ASCII Value : 13)
/*This 'enter' as an input is the devil. To keep it simple, i will keep calling it
as Enter below, and the enter is usually not displayed on screen*/
NOTE/IMPORTANT/CAUTION before proceeding: Till the time your stream doesn't get completely empty, you can't write new characters from the console into the stream. (This scenario only implies for the use of getchar and putchar, as shown below)
HERE IS YOUR CODE:
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
putchar(ch);
}
Loop Pass 1 :
a) You ask user to enter a character. // printf statement
b) getchar reads only a single character from stream.
c) putchar renders/displays only a single character from stream.
d) At first pass you provide input as 'a' but you also hit 'Enter'
e) Now, your stream is like a ***QUEUE***, at first pass, and at 1st place of
the queue, you have 'a' and at 2nd place 'enter'.
f) Once you do putchar, the first character , i.e. 'a' from the stream/queue
gets displayed.
e) Loop ends.
g) Output of this pass:
Enter a single character >>a
Loop Pass 2 :
a) You ask user to enter a character. // printf() statement
b) Unfortunately your stream isn't empty. It has an "enter" value from the
previous pass.
c) So, getchar(), reads the next single character, i.e. 'enter' from stream.
(This is where you were expecting to manually enter the next character,
but the system did it for you. Read the NOTE/IMPORTANT/CAUTION section
mentioned above)
d) putchar() displays 'enter' on screen, but since 'enter' is no displayable
thing, nothing gets displayed.
e) Output of this pass:
Enter a single character >>
Loop Pass 3 :
Similar as loop 1, only input this time is 'b'.
Loop Pass 4:
Similar as loop 2
and so on till 10 passes. (So, last character you will be able to enter is 'e'.)
INFERENCE/CONCLUSION:
So, long story short, you were expecting to enter the next character,
so that getchar would pick your entered value, but since from your
previous pass,'enter' value was already waiting in the stream,
it got displayed first, giving you such an illusion.
Thank you.
Let me know if your thoughts are different.
Loop on the even number of time, getchar() is not taking input from keyboard, but it is taken from the previous entered hit, so you would have also noticed that loop is only executed 5 times. So you have to clear the buffer, i.e. pressed entered, so that new character can be entered in the ch.
for (i = 0; i < 5; i++)
{
printf("\nEnter a single character >> "); // new line
ch = getchar();
while (getchar() != '\n'); //Clearung buffer.
putchar(ch);
}
Not sure if ideal, but this worked:
#include <stdio.h>
int main()
{
int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
getchar();
ch=getchar();
putchar(ch);
}
return 0;
}
I am a beginner . I tried this version of code and it gave the desired output.
#include <stdio.h>
int main()
{
int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
fflush(stdin);
ch = getchar();
putchar(ch);
printf("\n");
}
return 0;
}
Although getchar() gets a single character, control isn’t returned to your program until the user presses Enter. The getchar() function actually instructs C to accept input into a buffer, which is a memory area reserved for input. The buffer isn’t released until the user presses Enter, and then the buffer’s contents are released a character at a time. This means two things. One, the user can press the Backspace key to correct bad character input, as long as he or she hasn’t pressed Enter. Two, the Enter keypress is left on the input buffer if you don’t get rid of it.to Get rid of the Enter keypress insert an extra getchar() that captures the Enter but doesn’t do anything with it.so you just need an extra getchar() after ch = getchar();like this
#include <stdio.h>
#include <stdlib.h>
int main()
{ int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
getchar();
putchar(ch);
}
return 0;
}
I managed to get the desired result. I added a newline character and getchar() which picks up the extra character.
#include <stdio.h>
int main()
{
int i;
char ch;
for (i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
putchar(ch);
putchar('\n');
getchar();
}
return 0;
}
Related
I'm a newbie programmer. I have an assignment and I have some troubles about that. First of all my assignment is :
"Assume that you scan the input text in Turkish character by character from the keyboard, which you may think of as a default input device, until a ‘CTRL-D’ is pressed. You are supposed to skip punctuation characters as well as blank character. Your program will display the frequencies of letters and digits whenever the scanning process is done. You need to discuss the data structure as well as flowchart solution and hand in them with your code."
I did some research and found that the CTRL + D command corresponds to EOF. I wrote my code but it doesn't work as I want. Here is my code.
#include <stdio.h>
#include "stdlib.h"
#include <locale.h>
int main()
{
setlocale(LC_ALL, "Turkish");
char message[1000] = { ' ' };
char ch;
int i = 0;
printf("Please enter your message: ");
while (ch = getchar() != EOF )
{
message[i] = ch;
i++;
}
for (i; i >= 0; i--)
{
printf("%c", message[i]);
}
printf("\n\n");
system("PAUSE");
return 0;
}
When I run it, I write something and press ctrl + d, but as you can see in the picture, nothing happens. It just writes ^ D. Thank you for your help.
Ctrl-D corresponds to the integer character literal '\4' in C because A=1, B=2, C=3, D=4.
Your screenshot shows you're programming on Windows, so what you read about Ctrl-D being the same as EOF does not apply (it's a Unix/Linux/Mac thing).
To fix things, you need to read up until '\4' (or just 4; they are equivalent):
while ((ch = getchar()) != '\4')
{
message[i] = ch;
i++;
}
Note that you will still need to press your Enter or Return key for the line of text to be accepted, meaning you could type hello world^D what? i can still type? before hitting Enter to submit the text to your program. However, your program will stop reading at the ^D character, resulting in the message hello world being printed.
In the future, you might use something like printf("%d %c\n", message[i], message[i]); in a loop to print a list of the byte values you read.
Here's my code for exercise 1-13 in "The C Programming Language":
#include <stdio.h>
int main()
{
int c, currentIndex, currentLength;
currentLength = currentIndex = 0;
while ((c = getchar()) != EOF){
if (c == '\t' || c == '\n' || c == ' '){
if (currentLength == 0){
continue;
}
printf("Length of word %d: ||", currentIndex);
for (int i = 0; i < currentLength; i++){
putchar('-');
}
putchar('\n');
currentLength = 0;
++currentIndex;
} else {
++currentLength;
}
}
return 0;
}
So I can compile this and run it with ./a.out, but when I press "Enter" to start a new line of input ('\n') it runs the printf() and putchar() functions(and neither ' ' or '\t' trigger the output). The while loop doesn't end (it ends as it should with END-OF-FILE(CTRL-D)) but I'm wondering why these functions are being called when they are. It prevents input of multiple lines at a time. Here's an example of it's output:
how long are these words
Length of word 0: ||---
Length of word 1: ||----
Length of word 2: ||---
Length of word 3: ||-----
Length of word 4: ||-----
Just to be clear, I ONLY get the output from printf() and putchar() when I press "Enter". CTRL-D just ends the loop and the program.
getchar() by default is in buffered mode, so the characters are not given to your program until enter is pressed. Duplicate of this question: How to avoid press enter with any getchar()
The ENTER releases the buffer.
Up until the ENTER the data is not available to your code. Your code gets all the characters at the same time.
The operating system is in charge of maitaining the buffer (you might be able to change this aspect of your OS).
in c, any output (unless specifically set otherwise) is buffered.
Nothing is output until one of the following occurs:
fflush() is called
a '\n' is output
the buffer is filled.
so you could add a call to flush() after the call to printf()
Note: there are other word separators that you should probably be looking for, other than tab, space, newline.
Suggest adding: single quotes, double quotes, period, colon, semicolon, left paren, left brace, right paren, right brace, back tick.
I'm having trouble understanding exactly what getchar() does in this code, can anybody help explain it?
int main(void)
{
int i, n;
printf("This program prints a table of squares.\n");
printf("Enter number of entries in table: ");
scanf("%d", &n);
getchar();
for (i = 1; i <= n; i++) {
printf("%10d%10d\n", i, i * i);
if (i % 24 == 0) {
printf("Press Enter to continue...");
getchar();
}
}
return 0;
}
It blocks the program until the user presses enter. The character the user typed is just thrown away since the return value isn't passed to a local variable.
I looks like the intent is to add simple pagination functionality since it does this after every 24 lines.
getchar() returns the next character from the standard input (stdin).
In your program second getchar() occurence should be checked if the entered key is "Enter".Asci value of Enter key is 13.
getchar() returns a character from stdin.
Here each getchar(); waits for user to press a key so it can return a single character. It's here in code to wait for user interaction.
But the shell terminal do not pass the charater as soon as you press keyboard. It passes it to stdin stream only after you press enter/New line, which is also a character.
So, when you only press Enter/NL key, getchar() will receive 0xA.
But if you press some other character and then Enter/NL, the first getchar() will get that other character and subsequent getchar() will get 0xA. This is like a simple pipe mechanism.
I am new to C programming. And I was doing a practice, and the question goes like this: Use the ?: operator and the for statement to write a program that keeps taking the characters entered by the user until the character q is accounted.
And here is the program I wrote:
#include <stdio.h>
main()
{
int x, i=0;
for (x = 0; x == 'q'? 0 : 1; printf("Loop %d is finished\n",i))
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
x=getc(stdin);
putc(x,stdout);
++i;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
The problem is: every time I enter a "non-q" character, the loop seems to run twice.
I don't know what is wrong with my program.
Please help!
When you enter a non-q letter, you also hit Enter, which is read in the second loop.
To make the loop only run once per input, use fgets() to read an entire line of input at once, and check if the input string matches your expectations.
When you type a and then press Enter, the newline character becomes part of the stdin stream. After a is read, the next time you execute x=getc(stdin), the value of x is set to \n. That's why two iterations of the loop get executed.
The loop runs twice because when you enter a non-q character, you actually enter two characters - the non-q character and the newline '\n' character. x = getc(stdin); reads the non-q character from the stdin stream but the newline is still lying in the buffer of stdin which is read in the next getc call.
You should use fgets to read a line from the stream as others have suggested and then you can process the line. Also, you should specify the return type of main as int. I suggest the following changes -
#include <stdio.h>
int main(void)
{
int x, i = 0;
// array to store the input line
// assuming that the max length of
// the line is 10. +1 is for the
// terminating null added by fscanf to
// mark the end of the string
char line[10 + 1];
for (x = 0; x == 'q'? 0 : 1; printf("Loop %d is finished\n", i))
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
// fgets reads an input line of at most
// one less than sizeof line, i.e.,
// 10 characters from stdin and saves it
// in the array line and then adds a
// terminating null byte
fgets(line, sizeof line, stdin);
// assign the first character of line to x
x = line[0];
putc(x, stdout);
++i;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
When you enter a character, say 'x' and press enter, you actually input two characters, which are 'x' and '\n' also known as newline(when you hit enter). The '\n' becomes part of the input stream and the loop is executed for it as well.
Also, try inputting "xyz" and hit enter, the loop will be executed 4 times. For each 'x', 'y', 'z', and '\n'.
If you want the code to work one time for every input, use the function gets.
#include <stdio.h>
main()
{
int i=0;
char x[10];
for ( ; x[0]!='q'; printf("Loop %d is finished\n",i) )
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
gets(x);
i++;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
In this code we declared x as an string, the gets() function reads the whole line we entered, then in the condition part of the for loop, we check whether the first character of the string is 'q' or not.
My program scans from input and prints all the capital letters used.
Im trying to print the original input from stdin at the end of my program too.
But when i use printf, it seems to skip the first part of the input expression, printing the remaining stuff in my character array. Please help me see where the problem lies. -comments in code-
#include <stdio.h>
int main(void){
char input[81];
int letters[91];
int i;
//initialize arrays input and letters
for (i = 0; i < 90; i++) letters[i] = 2;
for (i = 0 ; i < 80; i++) input[i] = 'a';
i = 0;
//reads into input array until EOF
while((scanf("%c",input)!= EOF)){
//checks input for characters A-Z
if((input[i]>= 'A' && input[i]<= 'Z'))
letters[input[i]] = 1;
}
//prints capital letters from input that occur at least once
for(i = 'A'; i < 'Z'; i++){
if (letters[i]==1)
printf("%c", i);} // this output works fine, the scan worked??
//print blank line
printf("\n\n");
// print input
printf("%s\n", input); //This is where the incorrect output comes from.
return 0;}
does my original input change? why?
did my input not get scanned correctly in the first place?
please respond quickly!
Here:
while((scanf("%c",input)!= EOF)){
you're only ever reading characters into input[0]. This is fine for what you're doing for letters, but obviously when you try to print out input, it's not going to work as you expect.
When you fix it, you'll also need to remember to add a terminating \0 after the last input character.
The scanf loop reads your input one character at a time, and stores that one character in input[0]. When the scanf loop is completely finished, input[0] contains the last character read, and the rest of input is untouched.
To repair, you need to include i++ at the end of the scanf loop.
By the way, it would be clearer (and more efficient) to fill the input buffer with a single call to fgets then loop through the input buffer with: for (i=0; buf[i]!='\0'; i++) { ... }
You must do
while((scanf("%c",&input[i])!= EOF))
{i++;}
instead of this
while((scanf("%c",&input)!= EOF))
{}
What you are doing is scan the character into the address of the first element int the array everytime, hence it gets overwritten again and again. Remaining part of the input[] array is not being accessed, and hence does not change