Issue
I have question about EOF.
First of all, I am coding a simple program that is coping/printing the user's input.
However, the program copies the EOF also in the output.
For an example, my O.S is Window and my EOF works when I type (Enter -> cntrl + z -> Enter) in order. If I input "Hello" + Enter + EOF key combination, the output prints the weird letter('?') at the end of the copied user input.
How can I get rid of the '?' at the end of the output, and why is it happening?
#include <stdio.h>
void copy(char to[], char from[]);
main()
{
int i;
int c;
char origin[10];
char copied[10];
for(i = 0; (c = getchar()) != EOF; ++i)
{
origin[i] = c;
}
copy(copied, origin);
for(i = 0; i < 10; i++)
putchar(copied[i]);
}
void copy(char to[], char from[])
{
int i;
i = 0;
while((to[i] = from[i]) != '\0')
i++;
}
Solution
The problem is not related to EOF
at all, there are multiple issues in your code leading to potential undefined behavior and unwanted side-effects:
- The reading loop continues up to the end of file: if the input stream is longer than 10 bytes, the code will cause a buffer overrun, storing bytes beyond the end of the
origin
array. This is a first case of undefined behavior. - The local array
origin
is uninitialized, so its contents are indeterminate. You do not store a null terminator into it after the bytes read fromstdin
. - In the
copy
function, you rely on a null terminator to stop the copying loop, but since none was stored there, you access uninitialized contents after all bytes read fromstdin
have been copied. The null terminator test is combined with the assignment inwhile((to[i] = from[i]) != '\0')
. Accessing uninitialized data has undefined behavior. Furthermore, you keep reading fromorigin
until a null terminator is found, causing further undefined behavior if you end up reading beyond the end of the array, and even more so when writing beyond the end of thecopied
array. - The final loop outputs all 10 elements of the
copied
array. - Even if the array
origin
may by chance contain null bytes at the end, thus preventing undefined behavior in thecopy
function. The output loop would still output funny characters as you would not stop at the null terminator, but instead print it tostdout
, and again have undefined behavior when you read uninitialized contents at the end ofcopied
after that. - Also note that the prototype for
main
without arguments isint main(void)
. The syntax you used, without a return type, was common in the '70 and '80s but is now obsolete and should not be used anymore.
Here is a corrected version:
#include <stdio.h>
void copy(char to[], char from[]);
int main(void) {
int i;
int c;
char origin[10];
char copied[10];
for (i = 0; i < 10 - 1 && (c = getchar()) != EOF; i++) {
origin[i] = c;
}
origin[i] = '\0';
copy(copied, origin);
for (i = 0; copied[i] != '\0'; i++) {
putchar(copied[i]);
}
return 0;
}
void copy(char to[], char from[]) {
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
i++;
}
Answered By - chqrlie Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.