Performance impact of frequent isatty() calls
A quick benchmark showed that at least on Darwin, isatty isn't cached and it does an ioctl every time.10 000 checks of file descriptors 0 - 99 took just 0.4 seconds on 2.8GHz i7 (mac). I would say that calling printf costs far more than calling isatty.
Anyway, I would use a function pointer. At the start I would call one isatty and map a pointer to function (printf without ascii / printf with ascii) and then use that pointer.
Martin