Hola:
Hay programas que cuando piden varias líneas por el teclado usan el Ctrl-Z o el Ctrl-D para marcar el fin de texto y terminar la entrada de datos. Por ejemplo, sendmail usa Ctrl-Z y telnet usa Ctrl-D. Por eso te comenté lo de probar con Ctrl-Z. Buscando por google, he visto que muchos sistemas linux/unix interpretan Ctrl-D como EOF, así que quizás sea mejor opción. Ojo, esto sólo vale cuando el programa está pidiendo datos por teclado. Si no está pidiendo nada, posiblemente Ctrl-Z tenga el comportamiento que indica m0skit0.
En cuanto a que el stdin lea letras o números, no es totalmente correcto. Por la stdin, hagas lo que hagas, llegan bytes, luego es el programa C el que los almacena como int o como char. Si escribes una A, al programa C le llega un byte de valor 65, que es el correspondiente al ascii de la A. Si lo metes en un int es un 65 y si lo metes en un char es una 'A'. Si le das a la flecha o a un Ctrl-algo, si nadie lo interpreta, también le llegan bytes al programa. Normalmente estas teclas raras o combinaciones suelen ser uno o dos bytes. En caso de que sean dos, el primero suele ser un ascii <ESC> que corresponde a un 27 y luego otro valor correspondiente a la otra tecla. Por ejemplo, los Ctrl-Letra suelen ser al byte de la letra siendo A el 1, B el 2, C el 3, etc. Por ejemplo Ctrl-G es un beep y es un byte 7. Un retorno de carro (Ctrl-M) es un 13. Y de hecho, getchar() devuelve un int, que será 65 si es una A, 4 si es un Ctrl-D o un 26 si es Ctrl-Z.
En cualquier caso, no creo que el Ctrl-D llegue como un EOF tal cual está escrito en el código C (dices que es un -1). Ahí m0skit0 tiene razón y quizás la mejor forma sea leer hasta que llegue un caracter concreto, por ejemplo, el correspondiente a un byte 4 que es el del Ctrl-D. No es buena idea lo del /n porque entonces sólo podrías escribir una línea, salvo que pongas como criterio terminar la entrada de datos cuando lees una línea en blanco (es decir, dos /n seguidos, el de la línea anterior y el siguiente). En el caso de Ctrl-D, por ejemplo, puedes probar
for (nc = 0; getchar()!=4; ++nc);
Se bueno.