How to properly using EOF?


How to properly using EOF?



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.



enter image description here



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]) != '')
i++;
}





Not the problem, but you should use a standard int main(void) instead of main()
– Cool Guy
Jul 1 at 5:40


int main(void)


main()





EOF is not a value of char type (e.g. on computers where char-s are unsigned, EOF might be -1). So you cannot copy EOF, by definition!
– Basile Starynkevitch
Jul 1 at 6:24


EOF


char


char


unsigned


EOF


EOF





A good question. Just using a screen shot is a pity. Please paste text as text. To do to from windows in the CMD-window enable "Quick Edit Mode" in the window's properties' options TAB.
– alk
Jul 1 at 8:54





4 Answers
4



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:


EOF


origin


origin


stdin


copy


stdin


while((to[i] = from[i]) != '')


origin


copied


copied


origin


copy


stdout


copied


main


int main(void)



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] = '';

copy(copied, origin);

for (i = 0; copied[i] != ''; i++) {
putchar(copied[i]);
}

return 0;
}

void copy(char to, char from) {
int i;

i = 0;
while ((to[i] = from[i]) != '')
i++;
}



You forgot to NUL-terminate origin. So you invoke Undefined Behavior during copying. Use the following code to get input instead:


origin


for(i = 0; i < 9 && (c = getchar()) != EOF; ++i) /* `i < 9` to prevent array overruns */
{
origin[i] = c;
}
origin[i] = ''; /* NUL-terminate your string */



Also change the printing code to:


for(i = 0; copied[i] != ''; i++) /* Print until a NUL-terminator */
putchar(copied[i]);





No, this is the correct answer. A local array is not properly initialized by default (so the programmer should think of initializing it)
– Basile Starynkevitch
Jul 1 at 6:25






The origin[i] = ''; statement is correctly null-terminating the string in origin
– Basile Starynkevitch
Jul 1 at 6:31


origin[i] = '';


origin





@BasileStarynkevitch I needed three reparsings to see that 0 IS copied. Thanks.
– Yunnosch
Jul 1 at 6:31



You are unconditionally outputting all 10 members of your array.
You could fix by appending the often used '' at the end of the letters to output.
With a


''


origin[i] = '';



after reading in.



And finally outputting until that marker, instead of everything


for(i = 0; copied[i]!=''; i++)



This keeps your assumption that the arrays are large enough to keep the input (including the added ''). You should however protect against that, e.g by using a dual condition for any loop, checking against accessing beyound the highest allowed array index.


''





May also want to comment on how dangerous for(i = 0; (c = getchar()) != EOF; ++i) is... Input of "Hello Newb<nasty shellcode>" could be quite bad.
– David C. Rankin
Jul 1 at 6:50


for(i = 0; (c = getchar()) != EOF; ++i)


"Hello Newb<nasty shellcode>"



You are using an IDE (probably CodeBlocks) which is using page buffer between subsequent IO operation and that's why you actually get the output.



Next, you are forcing to print all ten elements of the array in the output for loop which is bad coding practice.



This simple snippet could help you


scanf("%10[^n]s",input);



Use it to read input from file ./youpro < file_name_where_to_fetch_input



Thanks to David C. Rankin in the comment to mention the error.





I think OPs description of how they input EOF is plausible.
– Yunnosch
Jul 1 at 6:27


EOF





Maybe, it is. I am not from windows background... and my answer is more towards Linux and in general when compiling from terminal... You can't do these magical combinations to enter EOF... So, an std practice should be followed and so as my ans. Might I be wrong on windows..
– ChandraKumar
Jul 1 at 6:42





"there is no way to enter 'EOF' as input"?? Of course there is. Ctrl+d on Linux generates a manual EOF and Ctrl+z does the same on windoze. But see: CTRL+Z does not generate EOF in Windows 10
– David C. Rankin
Jul 1 at 6:44


Ctrl+d


EOF


Ctrl+z





You are still out on a skinny branch regarding guessing at the IDE (which isn't really relevant anyway), but good first effort. Remember, when answering on StackOverflow, you step into the roll of Teacher. You want to make sure you are one of the good ones, and not one of the teachers that have left us all more confused than when we started the lesson. Keep up the good effort and always work to be thorough and correct.
– David C. Rankin
Jul 1 at 6:53






The conversion specifier for character classes does not have a trailing s, and the number specified must be one less than the size of the array. It should be written scanf("%9[^n]", origin);. Furthermore, this scanf() will fail if the user enters an empty line, causing undefined behavior if the return value of scanf() is ignored.
– chqrlie
Jul 1 at 10:50


s


scanf("%9[^n]", origin);


scanf()


scanf()






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to input without newline? (Python)

C++ thread error: no type named ‘type’ MINGW

Analog for TagView in flutter