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
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 am doing an exercise in which my program needs to output 20 lines of a file and then wait for user input. If the input is the character g, the program should stop executing. Otherwise, it should print another two lines and ask for input again.
When I execute the program I am only asked for input once. That is, when I input a character other than g, the program keeps executing (as it should) but doesn't ask for input again, it just outputs the rest of the file.
I tried debugging it but I did not see where the error could be. I also tried getting input with scanf(), fscanf(), getc() and getchar() but the program's behavior doesn't change. What am I missing?
#include <stdio.h>
#define LINES 20
#define ESCAPE_CHAR 'g'
// Error checking, opening file, etc.
// ...
char c;
int count = 0;
while ((c = getc(file)) != EOF)
{
// output
putc(c, stdout);
// increment count if character is linefeed
if (c == '\n')
++count;
// ask for character once 20 lines have been printed
if (count == LINES)
{
count = 0;
// exit loop if input is 'g'
/* I also tried scanf(), fscanf() and getc()
here and the results were the same. */
if (getchar() == ESCAPE_CHAR)
break;
}
}
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
I'm completely new to C and have this example from The C Programming Language book:
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* count line and words and characters in input */
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);
}
The code compiles fine in the terminal with: gcc -o count count.c
When I run it with: ./count it let's me test it, gives me a new line to type in the input. I type in, hit the Return and it gives me another blank line for my text input, not outputting anything.
What is it that I do wrong? I was doing some other examples with input and I was receiving an output, but none of the code that I use from this book works for me now.
Many thanks.
The value "EOF" is not equal to a newline aka '\n'. "EOF" is the value sent when you hit ctrl+d, when standard input (aka getchar()) is coming from the keyboard, or when you reach a file, if you're redirecting standard input from a file (which you would do with ./count < file).
Hit Ctrl-D, which is the EOF character for Linux, assuming that is what you are using.
The loop in the code says to iterate till EOF (End-of-File) character is read. If you are using Linux, this would be Ctrl+D. For Windows, you have to press Ctrl+Z and enter key.
If the intended outcome of the program is to count the number of lines, words and characters in the input, then it is important that there should be a clear demarcation of where the given input starts and where it ends.
In this particular program, The input starts when the while loop starts (and the input character is not EOF) and the input stops when the EOF character is entered.
The meaning and usage of EOF has to be clear.
EOF is a macro that is returned by stream functions to indicate an end-of-file condition. This symbol is declared in stdio.h.
When a comparison of the form:
((c = getchar()) != EOF)
is made, what happens internally is that the ASCII value of the character input in 'c' is compared to the ASCII value of EOF.
After you enter the input you hit 'Return'. 'Return' corresponds to New Line of Line feed and the ASCII value for this is 10 (Decimal).
EOF in ASCII corresponds to End of Transmission and has the ASCII value 4 (Decimal).
So if you keep hitting 'Return' after the inputs, the program will expect inputs infinitley. To indicate the end of input, EOF has to be input. EOF corresponds to Ctrl-D (ASCII value 4).
So to sum up, there is nothing wrong with your program. All you have to do is at the end of the input, instead of hitting 'Return' , Do a control-D.
Hm,I love K&R .
Got this question before, needs a ending.
As Ctrl+d, you can try:
ls | ./count