Program prints garbage upon EOF [duplicate] - c

This question already has answers here:
Difference between int and char in getchar/fgetc and putchar/fputc?
(2 answers)
Closed 3 years ago.
I'm reading through the K&R book and implemented the 'copy' example:
#include <stdio.h>
int main() {
char c;
while ((c = getchar()) != EOF) {
putchar(c);
}
return 0;
}
All normal input appears to work correctly but when an EOF (^D) is entered the program prints infinite "�" characters and I must halt the program manually.
I have tried using putchar(c); as well as printf("%c", c); to the same effect.
Does anyone know the cause of this?

Since c is of type char, an int value returned from getchar will be converted to the type char before it is compared to EOF.
Since the EOF is an in-band error mechanism, it has to be an error value that can be distinguished from all valid characters that could be returned. When you assign EOF to a char you discard information.
After executing:
char c = EOF;
the statement
c == EOF
is false.
Preserve the return type of getchar by doing:
int c;
instead of:
char c;

Using int c instead of char c should solve your issue

Related

getchar/putchar returns boxes with question marks when printing inputted characters

Playing around with code examples from K&R in Codeblocks on Windows 10 (Danish language). The following example works as expected:
#include <stdio.h>
int main() {
char c = 'a';
putchar(c);
}
However, the following prints a series of boxes with question marks, the same number as the number of characters I type:
#include <stdio.h>
int main() {
char c;
while (c = getchar() != '\n') {
putchar(c);
}
}
So it looks like an encoding issue. When run, a command prompt opens with "C:\Users\username\Desktop\filename.exe" in the header, and my username contains the Danish character "å" which is replaced by a "Õ". The command prompt uses the CP 850 character set.
(By the way, I'm not checking if the character equals EOF, since that produces odd results. Pressing enter prints the expected number of boxes, plus one for \n, but it doesn't end the program.)
You are seeing a problem of operator precedence here. As you can see on this chart, = has a lower precedence than !=.
This means that getchar() != '\n' is evaluated first.
To the compiler your code looks like this:
#include <stdio.h>
int main() {
char c;
while (c = (getchar() != '\n')) {
putchar(c);
}
}
Since 'c' is getting an incorrect value (the true/false evaluation of the expression), the output is incorrect, and the program gives the behavior you are seeing, however
#include <stdio.h>
int main() {
char c;
while ((c = getchar()) != '\n') { //<----notice brackets around c=getchar
putchar(c);
}
}
gives the output you are expecting. This illustrates the fact that you should always put brackets around such expressions to be safe.
This line is bad.
while (c = getchar() != '\n')
It should be:
while ((c = getchar()) != '\n')
There are already some correct answers within the scope of the question but there are a couple of wider problems that you need to address.
Firstly getchar() returns an int and it is important that you define the variable that takes the return value as an int so you can differentiate errors and end of file from valid chars.
Secondly, if you receive end of file or there is an error on stdin before the program encounters a \n, your code will loop forever. This is what the man page on my laptop says about getchar()
If successful, these routines return the next requested object from the stream. Character values are returned as an unsigned char converted to an int. If the stream is at end-of-file or a read error occurs, the routines return EOF.
So once getchar() returns EOF it will return EOF all the time. You need to address this in your loop condition:
#include <stdio.h>
int main()
{
int c; // c declared as int
while ((c = getchar()) != EOF && c != '\n'))
{
putchar(c);
}
if (c == EOF)
{
// handle errors and end of file as you see fit
}
}
Edit: You get the boxes because of the lack of parenthesis around the assignment, look at this question for reference as to why you should have parenthesis around an assignment used as a truth value...
Also, there is something else that is also wrong with this program, consider this example:-
For example:
What you actually wanted:-
ABCD
< newline >
What you actually typed:-
ABCD
And since the program didn't find the '\n' anywhere in the code, it leads to undefined behavior since it goes out of bounds to find it...
There are two possible solutions when your input does not contain a '\n':-
Use EOF (Suggested by many since it the best possible solution for accepting every input...)
int main() {
char c;
while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
an assignment in a condition... */
putchar(c);
}
Add a newline to your input:-
int main() {
char c;
// Use fputc to modify input...
fputc('\n', stdin);
while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
an assignment in a condition... */
putchar(c);
}
But, beware! This method will stop at the first iteration of newline it gets, so if you have something outside of the '\n', well it won't be printed...

Basic character counting in C [duplicate]

This question already has answers here:
Why doesn't getchar() recognise return as EOF on the console?
(8 answers)
Testing getchar() == EOF doesn't work as expected
(2 answers)
Closed 5 years ago.
Having trouble getting an actual count, but I'm not seeing what I'm doing wrong.
I type in a word, hit enter, then nothing happens and it keeps running.
int main(void)
{
double nc;
for (nc = 0; getchar() != EOF; ++nc)
;
printf ("%.0f\n", nc);
}
When reading from an interactive console input, getchar() will not return EOF just because the user stops typing or presses return, it will if necessary wait for the user to enter something new on the keyboard. So, the for-loop is not terminated.
You have to use a special key combination (dependent on the operating system used) to signal end-of-file or check for some other input to terminate the loop (like end-of-line, for example)
As noted, EOF will not be true until ^D is entered. Terminate on that, but also check for the newline character. Check this older Question for some good background on this here:
getchar() != EOF
Here is the program written using ints and checking for newline or EOF
// Customize AT_END Macro to return true based on some condition
#define AT_END(ch) (((ch)=='\n') || ((ch)==EOF))
int main(void)
{
int inpChar = getchar();
int nc = 0;
while (!AT_END(inpChar)) {
nc++;
inpChar = getchar();
};
printf("Number of chars=%d\n", nc);
}

Why loop is not getting terminated? [duplicate]

This question already has answers here:
What is EOF in the C programming language?
(10 answers)
Closed 6 years ago.
int main()
{
int c;
c = getchar();
while (c!=EOF){
putchar(c);
c=getchar();
}
return 0;
}
in above code when I input value -1 why the loop doesn`t get terminated.
value of EOF = -1 I got from this code,
main()
{
printf("EOF is %d\n",EOF);
}
code get terminated when I use Ctrl+D,is there any other way to terminate the same code without using Ctrl+D.
Because typing -1 on console doesn't generate EOF. Instead getchar() reads it as two separate characters '-' and '1'.
If you want to terminate it with -1 input then you have to keep track of two characters and compare them to exit the loop instead of comparing against EOF. But that is really not equivalent of generating an EOF.
Another option to terminate is to redirect standard input to a file via input redirection < in console. When the reading from input file ends it will signal an EOF.
If you want to loop out of the code without pressing ctrl+D then there are multiple ways of doing it. I will show you the easiest and inefficient way of doing it using a basic if condition. Go through the code and if you have any doubt please feel free to comment on it.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int c;
c = getchar();
while ((c != EOF))
{
if (c == 'i')
break;
putchar(c);
c = getchar();
}
return 0;
}

Program stops running after while loop

So, it has been some time since I last programmed in C, and now I am trying to get back into C again, but I am having trouble with my program. The program is very simple, I use getchar to store chars in a char array, but for some reason the program stops running after my while loop.
#include <stdio.h>
#define MAXLINE 1000
int main(){
char c;
char input[MAXLINE];
int i = 0;
while((c = getchar()) != EOF){
input[i] = c;
++i;
}
printf("Still running");
}
So, my program doesn't print "Still running".
Send EOF (Ctrl+D for *nix Ctrl+Z for Win), it will show the Still running.
root#Linux-VirtualBox:~/program/progEdit# ./stktest.o
sdf
fdf
sdf
Still runningroot#Linux-VirtualBox:~/program/progEdit#
Your program only works by luck, because getchar returns an int not a char. The reason for this is that getchar may return EOF, which is not necessarily representable as a char.
To fix this bug, you need to replace char c with int c.

Strange phenomenon of console input to a C program [duplicate]

This question already has an answer here:
C input - getchar()
(1 answer)
Closed 9 years ago.
I am runing the following simple program using Visual Studio 2010. The purpose is to see what will happen if I define variable c as char or int, since the getchar() function returns an integer (A widely known pitfall in the C programming language, refer to int c = getchar()?).
#include <stdio.h>
int main()
{
char c;
//int c;
while((c = getchar()) != EOF)
putchar(c);
printf("%d\n",c);
return 0;
}
When I input some characters from the console to this program, I found a strange phenomenon, as shown in the following figure. If the EOF as input follows a sequence of characters (the 1st line), it can not be correctly recognized (a small right arrow is ouput, 2nd line). However, if it is input standalone (4th line), it can be correctly recognized and the program terminates.
I didn't test this program on Linux, but can someone explain why this happen?
What you're describing is, basically, the way terminals are designed.
You need to remember that EOF is not a character. When you type "ABCDEFCTRL-Z", you're entering eight input characters: A, B, C, D, E, F, CTRL-Z, and Return. The only thing special about CTRL-Z (or CTRL-D on Unix/Linux) is that if you type that as the first thing on a new line, then instead of entering a character, the terminal behaves as though the end of the input file has been reached. The getchar() function will return EOF. Since any possible value that can fit into an unsigned char is a valid return value for getchar(), EOF can be distinguished from any valid return value by virtue of being negative, which is why getchar() and family are defined to return int.
If you change your program a little bit and put two printf statements, you will see that the program actually can read the CRTL+Z combination correctly (ASCII code 26):
#include <stdio.h>
int main()
{
char c;
//int c;
while((c = getchar()) != EOF) {
printf("%d\n",c);
putchar(c);
printf("\n");
}
printf("%d\n",c);
return 0;
}
But as the above answer tells, it must be on it's own line; in order to be interpreted correctly. Because on windows, each line has an EOL characters except the last line. There is an EOF character after the last line.

Resources