I found getchar() is behaving differently in some situations.
In the following code, it devours the newline character in the input.
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
}
}
The input and output in the terminal looks like this.
j
j
b
b
asdf
asdf
ashdfn
ashdfn
It exactly duplicates the input and ignores the newline character in the input due to return key I pressed after each input.
However, if there is a printf() statement inside the loop, it no longer ignores the newline character.
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
printf("\n");
}
}
The input and output in the terminal looks like this.
j
j
b
b
asdf
a
s
d
f
ashdfn
a
s
h
d
f
n
It echoes the newline character, which was used to be ignored in the previous situation.
Could you tell me why there is a difference and how does it behave exactly?
In first case, it reads one character - getchar() and prints it - putchar(), so there is not newline or '\n' after each character. The newline is the one you entered with enter key press.
While in 2nd case, you have printf("\n") which prints new line after every character is printed - through putchar().
getchar reads a character at a time. When you input 123 and press Enter key then this input goes to the C standard buffer with one more character \n (generated on pressing Enter key). Now from there getchar reads a character at a time and rest of the characters in input stream left behind for the next call of getchar.
Now, to answer your question I am going to explain it with a simple program;
#include <stdio.h>
int main(void)
{
int c, b;
c = getchar();
putchar(c);
b = getchar();
putchar(b);
b = getchar();
putchar(b);
}
Giving the input 123, the input stream of the buffer would be
123\n
Having four chars; '1', '2', '3' and '\n'.
First getchar reads 1 and then putchar output this character. Now the buffer have 23\n. Next call of getchar reads 2 and next to it will read 3. Finally \n is left behind for the next call of getchar. Hence the output will be
123
Now inputting the character one by one as in your first example. On passing j you are passing j\n to the buffer. First call of getchar will read j and is putchar output this on screen. Next call will read \n and putchar print this out on the screen but the effect is not seen to you until the read of next character. On third call of getchar, b is read but this time it goes to the next line on the output screen. This is because of the \n character read previously by getchar. Finally \n is left behind in the buffer for next call of getchar.
Now coming to your first example
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
}
}
This will work similarly as stated above.
Now coming to your second example
#include <stdio.h>
// copy input to output; 1st version
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
printf("\n");
}
}
This is printing two newlines after each of character but supposed to print a single character, right?
It is printing what it should! This is because it is printing a newline not only for characters j, b...etc but also for newline character \n. Take simple input j\n, b\n.
On first call of getchar, j is read and printed with a newline by printf then on next call \n is printed along with a newline and the output looks like
j
//The newline printed by printf along with j
//The newline printed by printf along with \n
b
It is not echoing the newline. getchar() is buffered input. Also, getchar() is of echoing type. The control will wait until you press Enter key from the keyboard.
If you do
abcdeEnter
since getchar() is of echoing type, it reads single char from the buffer until it encounters newline and the same char is echoed. The putchar() prints the received char on the terminal. The newline which is being output is entered by you when you press Enter.
The same thing happens in the second case, but one extra line is added because of printf.
Check http://ideone.com/H2kqBq
#include <stdio.h>
int main()
{
int c;
while((c = getchar()) != EOF)
{
putchar(c);
printf("\n");
}
}
The output is not as you have specified here.
The behaviour of getchar() and putchar() is consistent
in my opinion what is happening is, when you enter a character at the terminal, suppose 'a' and then press Enter, actually two characters are getting buffered in the input stream
'a' and '\n'
so the loop runs twice to putchar these two characters, that is why your next input starts at new line
(you may check that by using:
if(c!='\n') putchar(c);
this will cause the '\n' not to be printed and you would input on the same line)
when you add printf("\n"), it will also be printed twice because the loop will still run two times as there are two characters in the input stream.
so you will get
a
(newline from printf)
in the first iteration of the loop
(newline from input buffer)
(newline from printf)
in the second iteration
Related
I'm currently learning C by a book "C Programming a modern approach" and encountered this code. When I tried to run it, after typing consecutive characters like 'abc' and hitting Enter (new line), nothing was printed. Please explain what is going on here.
char ch;
do {
scanf("%c" , &ch);
} while (ch != '\n');
printf("%c", ch);
You're asking the user to input a character using scanf. This is happening in a loop until the user inputs a '\n' or newline character (the same as pressing the enter key), which is when the loop will break.
Your print statement will then print the character in the variable ch, which at that point will be '\n' (since this variable just stores one character, the last one you typed).
This newline character will probably be invisible when you run your program so you may not be seeing it. You can add another print statement after the loop and if that print statement starts at a newline, you know that the '\n' was printed on the previous line.
Something like:
#include <stdio.h>
int main()
{
char ch;
do
{
scanf("%c" , &ch);
} while (ch != '\n');
printf("%c", ch);
printf("I should show up on a newline");
return 0;
}
The code you provided reads characters from the input using the scanf() function and stores them in the variable ch until a newline character (\n) is encountered. After that, the program prints the last character that was read, which is the newline character.
The reason you are not seeing any output when you enter characters followed by a newline character is because the printf() statement is only executed after the loop has finished running. So, the program is waiting for you to enter a newline character to terminate the loop and print the last character that was read.
If you want to see the characters you enter, you can add a printf() statement inside the loop, like this:
char ch;
do {
scanf("%c" , &ch);
printf("%c", ch);
} while (ch != '\n');
This will print out each character as it is read from the input, so you can see what you're typing. Happy coding :)
When I tried to run it, after typing consecutive characters like abc and hitting Enter (new line), nothing was printed.
Well with the posted code, if the loop even finishes, the last byte read by scanf("%c", &ch) and stored into ch is the newline character. Hence printf("%c", ch) outputs this newline and it seems nothing is printed but something is, the newline which is invisible on the terminal but does move the cursor to the next line.
You can make this more explicit by changing the printf call to this:
printf("last value: '%c'\n", ch);
Note however that the posted code is not a recommended way to read the contents of the input stream:
scanf("%c", &ch) may fail to read a byte if the stream is at end of file. Failure to test this condition leads to undefined behavior (ch is unmodified, hence stays uninitialized if the input stream is an empty file) or to an infinite loop as ch may never receive a newline.
this code is a typical example of a do / while with a classic bug. It would be much better to write the code using getchar() and a while loop.
Here is a modified version:
#include <stdio.h>
int main(void) {
int c; // must use int to distinguish EOF from all valid byte values
int count = 0; // to tell whether a byte was read at all
char ch = 0; // the last byte read
// read all bytes from the input stream until end of file or a newline
while ((c = getchar()) != EOF && c != '\n') {
ch = (char)c;
count++;
}
if (count == 0) {
printf("no characters entered: ");
if (c == EOF) {
printf("end of file or read error\n");
} else {
printf("empty line\n");
}
} else {
printf("last character on line is '%c'\n", ch);
if (c == EOF) {
printf("end of file or input error encountered\n");
}
}
return 0;
}
I have this little program:
#include <stdio.h>
int main(){
int c;
while(c != EOF){
printf("Enter character\n");
c = getchar();
printf("Character: %c\n", c);
}
printf("FIN\n");
return 0;
}
The output of the terminal seems odd, because the while loop gets executed twice after a character was entered:
Enter character
a
Character: a //This should be the last output after a char was entered, but the loop gets executed a second time without waiting for a keyboard-input:
Enter character
Character:
Enter character
In the terminal I'm compiling and running the code like this:
gcc main.c
./a.out
What am I doing wrong?
Thanks for the answers, It's the lf entered by enter .... It's so obvious :D
You are entering 2 characters, the 'a' and a LF.
The while test is not made until both have been processed.
As soon as you press enter, a newline character gets added to the input stream. So your program actually reads two characters: a and \n. This newline character is read by getchar() and assigned to c in the second iteration and you can actually see it being printed as an empty line. Before printing c, you could use a break statement to get out of the loop: if (c == '\n') break;
If you enter abc, you will see the empty line is printed after c.
For starters your program has undefined behavior because you are using uninitialized variable c in the condition of the while loop
int c;
while(c != EOF){
//...
The function getchar also reads white space characters as for example the new line character '\n' that is placed in the buffer after pressing the Enter key.
Another problem is that you are checking the variable c after reading and outputting it
while(c != EOF){
printf("Enter character\n");
c = getchar();
printf("Character: %c\n", c);
}
Instead of getchar you should use scanf as for example
char c;
while ( scanf( " %c", &c ) == 1 )
{
//...
}
Pay attention to the blank before the conversion specifier %c. This blank means that white space characters will be skipped.
I have been experimenting with getchar(), putchar() and have been trying to use EOF. Below is the snippet of code I have been experimenting with.
#include <stdio.h>
int main(void)
{
int c;
c = getchar();
while(c != EOF)
{
putchar(c);
printf("\n");
printf("%d\n", EOF);
c = getchar();
}
return 0;
}
Input: -
a
Expected output: -
a //Due to putchar()
-1 //Value of EOF
//Now the cursor should come in next line and wait for next character.
Output getting in real time: -
a
-1
-1
//Cursor waiting for next character.
I am not able to comprehend the reason why the output is showing -1 two times.
Your code comment says
//Now the cursor should come in next line and wait for next character.
But the second loop doesn't wait. It reads the newline that was already entered, and this is shown by the extra blank line in the output.
After the first input before the loop
c = getchar();
the input buffer contains the new line character '\n' that corresponds to the pressed key Enter.
So in the while loop there are outputted
a
and
-1
due to the statement
printf("%d\n", EOF);
After that this statement in the loop
c = getchar();
reads the new line character that is present in the input buffer. So again this statement
printf("%d\n", EOF);
outputs
-1
I was practicing C program that i read from The C ANSI Programming Language Second Edition
I learn about getchar() function.And the book say that getchar() read the character from stdin until newline character or EOF has been reached.And in the book i try to rewrite the program to count character using getchar() function.The code is fine when compiling. The problem is the code unable to display the long of character.
Here is the code:
#include <stdio.h>
int main (void){
long nc;
nc=0;
while(getchar()!=EOF)
nc++;
printf("%ld\n",nc);
return 0;
}
But when i change the EOF to newline character \n the code working as i expected but only
display the long of character only one line. After that the code terminate.
My question is what is EOF exactly is and what is the difference between EOF and newline character.
Is there other way to fix this program?
getchar() returns EOF when you get to the end of the file. It returns \n when you get to the end of the line. This is why your loop finishes when it gets to the end of the line if you replace EOF with \n.
EOF means End of File and you get that when your getting to the end of a file with getchar(). You get \n when you get to the end of a line.
When you now want it, so that it prints the text again use this:
#include <stdio.h>
int main(void) {
int c, nc = 0;
while ((c = getchar()) != '\n') {
nc++;
putchar(c);
}
printf("%d\n",nc);
return 0;
}
EOF is the end of file. It does not mean the end of your "long of character". If you just type many characters occupying several lines on the command line screen, the program still does not get the EOF unless you type Ctrl+D simulating the end of file. When you change EOF to "\n", the program requires the end of line. And when you finish the first line, the program get the end of the first line and run. That is why the code works as you expected but only display the long of character only one line.
I am having a problem scanning chars into an array. Every time I do it will skip the next scan and go to the next. I know what is happening because the input also adds '\n' to the input but I do not know how to remedy the cause of it. Here is some sample code:
char charray [MAX], ffs;
int inarray [MAX], i;
for (i = 0; i < MAX; i++)
{
charray[i] = getchar();
printf ("%c\n",charray[i]);
scanf ("%d", &inarray[i]);
printf ("%d\n",inarray[i]);
}
You can do like this.
while((c = getchar()) != '\n')
{
putchar(c);
}
this may solve your problem. or you can go till EOF also.
You are reading from the standard input with 2 functions: getchar() and scanf(). You need to understand how they work.
getchar() is easy: it returns the next available character in the input stream (or waits for one or returns EOF)
scanf("%d", ...) is more complex: first, it optionally discards whitespace (spaces, enters, tabs, ...), then it reads as many characters as possible to represent an integer, and stops at the first character that can't be used for integers, like a '\n'.
As you have them in a loop, your getchar() call will get the character that stopped the scanf() and the next scanf() will procedd from there.
If your input is something like "q1w22e333r4444" (with MAX == 4), your program will work.
If your input is something like
q 1
w 22
e 333
r 4444
after the first time through the loop (where charray[0] gets 'q' and inarray[0] gets 1), the getchar() will get '\n' leaving the 'w' "ready" for scanf, which of course fails ... and is then "caught" by the next getchar(); and the "22" gets assigned in the 3rd time through the loop (to inarray[2]).
So, you need to review your code.
Also, scanf() returns a value. Use that value
if (scanf("%d", &inarray[i]) != 1) /* error */;
You should actually scan a string into the array directly, rather than characters using scanf("%s",&charray);
However your code will work if you add a while(getchar() != '\n' ); statement. This will get all characters till the '\n'.
charray[i] = getchar();
do{
c = getchar();
}while(c != '\n' && c!= EOF);
printf ("%c\n",charray[i]);
scanf ("%d", &inarray[i]);
do{
c = getchar();
}while(c != '\n' && c!= EOF);
printf ("%d\n",inarray[i]);