たとえばプログラムやる人ならわかると思うけど、0には特別な意味を持たせることがある。
たとえば配列に文字を入れていき、最後に0を入れたところを終わりとする決まり。その最後の印として0を使ったりする。
でも、べつに実際は0でなくてもいい。1でもいいし、2でもいいし、'A'でも'B'でも何でもいい。その配列を読む仕組みを自分で決めて、たとえば
文字列の最後を示す印に'A'をつかったって良い。 ただ、実際は0が都合がいいから0が使われてるだけ。 もちろん0の後ろに文字を続けたっていい。

EOFも同じで、ただの印。テキストファイルの終端を表す。
べつにEOFとしてどんな数字を使ってもいい。ただ、実際は1111111111..... が都合がいいから、11111111111....がEOFとして使われてるだけ。
(-1は、全部のビットが1の状態。11111111......)
(int型が32bitだとしたら、EOFはint型なので、実際はビットは 11111111111111111111111111111111)

たとえば、ファイルの最後にEOFが無くてもいいし、文字列の最後に0が無くてもいい。
'A'をEOFとして扱ってもいいし、文字列の最後を'A'として扱ってもいい。自分でデータを読む関数を書くときに、それがわかってれば実は何を使っても書ける。
ただ、一般的にEOFは-1だし、文字列の最後は0にするのが普通だから、他の人はテキストデータを読むときに、そういう形で記録されてることを期待してデータを読む。
だから一般的な0やEOFに合わせた方が他人にも使いやすいデータになるだろうし、他人の作った関数で処理するときも上手く動くだろうってだけの理由。
だから文字列の最後を意味する数字や、テキストファイルの最後を意味する数字がほぼ固定されてる。でも実際は何でもいい。関数を書く本人がわかってれば何を使っても動く。