I'd like to ask some clarifying questions: using your example of bc, are you planning to have your "C" stream start up the bc program? If so, are you constrained because the "C" tool is binary only (you don't have access to the source code for the tool)?
If you have access to the source code, you could abstract out the relevant code, wrap it up in a "C" function like "void bc(const char* input, char* output)", and in your ViewController you would call bc with the text (converted to C-string) and a character string buffer internal to view controller to receive the result. When bc returns, you take the resulting string and update the view. If the function is going to take a long time, you might want to run in a dispatch queue, so it runs on a background thread.
If you have to use the actual "C" program binary, you will have to set up pipes, or some other inter-process mechanism, to feed the string from the text field into the stdin stream of the tool binary, and get the text string from stdout.