below is the code
Code :
#include <stdio.h>
int main(void)
{
int ch;
while((ch = getchar()) != 'h')
putchar(ch);
return 0;
}
Question :
1.)So as usual i just run this code , due to curiosity when the program prompt for input , i insert ^z(CTRL + Z) which is EOF (Windows 7 Command Prompt) , but all i get is infinite looping of character printing.
2.)From the code , my logic is that since i input ^z to the program , it'll just evaluate the logic (ch = getchar()) != 'h' and value true or 1 will be returned and character ^z will be printed out.But instead different result is yield.
When you press ^Z, the program notices the input stream was closed, but you keep on using getchar(), so you get EOF. This loops infinitely, since you can't input 'h' anymore. Note that only 'h' (not 'A', not ^M, and also not ^Z) can stop the program, since you loop if you don't get a 'h'.
In other words, if you want to stop if anything else but 'h' is entered, then do
do
{
ch = getchar();
putchar(ch);
} while (ch == 'h');
EOF is typically defined as -1 (but it's implementation specific). When you call putchar(-1), it will be converted to unsigned char, and become the value 255, which is then output (ÿ unless I'm mistaken).
EOF is an integer with an implementation-defined negative value. Your code loops indefinitely because only entering 'h' would make it finish. But once it reads EOF, which is != 'h', it enters an infinite loop because the standard input is closed and there is nothing that can make it return anything else.
Related
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;
}
}
I have been trying to understand how EOF works. In my code (on Windows) invoking EOF (Ctrl+Z and Enter) doesn't work the first time and I have to provide two EOF for it to actually stop reading input. Also, the first EOF gets read as some garbage character which gets displayed when I print the input. (We can see the garbage characters being display at the end in the output provided).
This is my code:-
#include<stdio.h>
#define Max 1000
int main()
{
char c, text[Max];
int i = 0;
while((c = getchar()) != EOF)
{
text[i] = c;
i++;
}
printf("\nEntered Text: \n");
puts(text);
return 0;
}
My Output:
I have this doubt:-
Why are two EOFs being required? and how do I prevent the first one from being read (as some garbage) and stored as part of my input?
Control-Z is only recognized as EOF when at the start of a new line. Therefore, if you want to detect it in the middle of a line, you'll need to do so yourself.
So change this line:
while((c = getchar()) != EOF)
to this:
while((c = getchar()) != EOF && c != CTRL_Z)
and then add:
#define CTRL_Z ('Z' & 0x1f)
at the top of your program.
You may still need to type a return after the Ctrl-z to get the buffered input to be read by the program, but it should discard everything after the ^Z.
The following solution fixes the Ctrl+Z problem and the garbage output and also blocks a buffer overrun. I have commented the changes:
#include <stdio.h>
#define Max 1000
#define CTRL_Z 26 // Ctrl+Z is ASCII/ANSI 26
int main()
{
int c ; // getchar() returns int
char text[Max + 1] ; // +1 to acommodate terminating nul
int i = 0;
while( i < Max && // Bounds check
(c = getchar()) != EOF &&
c != CTRL_Z ) // Check for ^Z when not start of input buffer
{
text[i] = c;
i++;
}
text[i] = 0 ; // Terminate string after last added character
printf( "\nEntered Text:\n" );
puts( text );
return 0;
}
The reason for this behavior is somewhat arcane, but end-of-file is not the same as Ctrl-Z. The console generates an end-of-file causing getchar() to return EOF (-1) if and only if the console input buffer is empty, otherwise it inserts the ASCII SUB (26) character into the stream. The use of SUB was originally to do with MS-DOS compatibility with the even earlier CP/M operating system. In particular CP/M files were composed of fixed length records, so a ^Z in the middle of a record, was used to indicate the end of valid data for files that were not an exact multiple of the record length. In the console, the SUB is readable rather than generating an EOF if it is not at the start of the input buffer and all characters after the SUB are discarded. It is all a messy hangover from way-back.
Try changing the type of c to int as EOF can be a negative number and commonly it is defined as -1. char might or might not be able to store -1. Also, do not forget to end the string with \0 before passing it to puts.
The logic that Windows terminals follow with regard to ^Z in keyboard input (at least in their default configuration) is as follows:
The Ctrl-Z combination itself does not cause the input line buffer to get pushed to the waiting application. This key combination simply generates ^Z character in the input buffer. You have to press Enter to finish that line buffer and send it to the application.
You can actually keep entering additional characters after ^Z and before pressing Enter.
If the input line does not begin with ^Z, but contains ^Z inside, then the application will receive that line up to and including the first ^Z character (read as \x1A character). The rest of the input is discarded.
E.g. if you type in
Hello^Z World^Z123
and press Enter your C program will actually read Hello\x1A sequence. EOF condition will not arise.
If the input line begins with ^Z, the whole line is discarded and EOF condition is set.
E.g. if you input
^ZHello World
and press Enter your program will read nothing and immediately detect EOF.
This is the behavior you observe in your experiments. Just keep in mind that the result of getchar() should be received into an int variable, not a char variable.
I have a program that is supposed to get input from a user until it receives EOF.
\n or white spaces are considered as legal chars,
but the console recognizes neither ^z nor ^d as EOF and the program continues to run until stopped manually.
Tried both:
while (currChar != EOF)
{
scanf("%c", &currChar);
}
and:
scanf("%c", &currChar);
if (currChar==EOF)
break;
scanf() doesn't set the variable to EOF when it gets to the end of the input, it returns EOF. So you have to test the value of the function.
while (scanf("%c", &currChar) != EOF) {
...
}
Well, EOF is not a character. It's an integer constant with the value of -1. With that said if you enter with the value of EOF, your char variable would read only the - (minus) from -1 value. That's why the loop won't stop, they'll never be equal.
*Note: I'm using windows, so EOF is ctrl + Z for me.
For a while I've noticed an EOF input seems to behave differently in isolation than it does when accompanied by other input. For example, ^Z (the EOF command for windows in command prompt) and a^Z seem to cause different behavior in the following code:
#include <stdio.h>
#define MAX 1000
int getline(char s[]);
main() {
int line;
char arr[MAX];
while( (line = getline(arr)) != EOF)
printf("%s",arr);
system("Pause");
return 0;
}
int getline(char s[])
{
int c, i = 0;
while ((c = getchar()) != EOF && c != '\n') {
s[i++] = c;
}
if (c == '\n') {
s[i++] = c;
}
else
return EOF;
s[i] = '\0';
return 1;
}
If I input ^Z + enter in the command prompt, the program predictably jumps to system("Pause"); However, if I input abc^Z + enter, nothing happens, as though EOF was ignored and a '\n' command was never received. If, at this point, I press enter again, it shows the following:
I've been tinkering with and debugging this code and small variations of it for over an hour now and can't seem to find anything wrong with it. In theory, if I input abc^Z + enter, I expect the input to be interpreted as abcEOF\n, which would give:
s[0] = 'a'
s[1] = 'b'
s[2] = 'c'
i = 3 when loop breaks from c = EOF
if (c == '\n') skipped since c = EOF
leads to else -> return EOF
in main(), line = EOF since that is what the function getline returned
while loop breaks because of above
system("Pause"); follows
Is there something wrong with my code that I'm overlooking or is there some quirk to EOF or command prompt that I should be aware of? I'm almost certain this isn't the only instance where mixing ^Z with other values caused unintended behavior.
Don't think of CTRL-Z as the end-of-file character, there is actually a real character with code point 26 (which is what you'd normally expect CTRL-Z to generate).
Instead, think of CTRL-Z as a way for your terminal device to indicate the end of the input stream to your program. If you were to read a real file of the disk and it contained CTRL-Z, it should keep going (though that may not be the case in certain implementations where you, for example, open it with the mode r instead of rb).
In Windows, that translation of CTRL-Z to the end-stream operation only happens when it appears at the start of the line which is why you're not getting EOF when you enter abcCTRL-Z.
When you enter CTRL-Z on a character position that isn't the start of the line, it's treated as a real CTRL-Z, not a stream-closing operation. That's why you're getting that → character, which is the printable character at code point 26.
It is the normal behaviour of getchar..
getchar() is a standard function and requires you to press *ENTER* to get the input
Many compilers/platforms support the non-standard getch() that does not require ENTER.
EOF is not a character. The EOF is a macro that getchar() returns when it reaches the end of input or encounters some kind of error
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