Srs,
O problema com o gets() é tão somente a possibilidade de obter um buffer overrun, se o ponteiro não apontar para um buffer de tamanho suficiente. Por isso ele deve ser evitado.
Já os file descriptors stdin e stdout são bufferizados até que um caracter \n seja encontrado. Nesse caso, e no caso do buffer ficar cheio, um fflush() é automaticamente chamado pela libc.
O código do Marmota provavelmente está sofrendo do seguinte comportamento: As funções gets() e scanf() parecem estar sendo chamadas antes das chamadas a printf(). Não é o caso... como não existem caracteres \n no fim das strings, então o buffer é preenchido e não mostrado (até enchê-lo... tipicamente a libc determina um buffer de 128 bytes, mas isso pode ser mudado via função setvbuf().
Ou seja, stdout é bufferizado por linha. O descritor stderr, por outro lado, não tem esse problema. Ele não é bufferizado! Para evitar o buffering em stdout pode-se usar:
setvbuf(stdout, NULL, _IONBUF, 0);
Já stdin, bufferizado ou não, neste caso, não faz diferença, já que o a tecla <ENTER> (\n) e usada para aceitar a entrada do usuário, descarregando o buffer.
[]s
Fred