Well then try explaining ctrl+c vs ctrl+d to someone who's never touched a terminal at all. Starts off so easily... "see one tells the program to stop" the other, well, if you're in a shell... or some programs... oh god. IDK anymore, just assume it works. What was the question?"
Maybe you can correct me if I'm wrong, but I've always considered Ctrl+C and Ctrl+D to be signals that you can send a process rather than explicit characters. You might also get some stdout for those key combinations because ???, but they should be thought of as signals rather than as characters you're sending via stdin.
Hoping Cunningham's Law comes into play with this comment. :)
When the TTY device takes (by default) Ctrl+C or Ctrl+D, it sends the signals to the program.
The TTY's 'line discipline' (the policy for when the program's STDIN can read from a line of input) can be changed from a default 'cooked' to a 'raw mode'. In with raw mode line discipline the Ctrl+C doesn't send the signal. Presumably that's why e.g. vi or emacs don't just close on Ctrl+C.
> Now you press ^Z. Since the line discipline has been configured to intercept this character (^Z is a single byte, with ASCII code 26), you don't have to wait for the editor to complete its task and start reading from the TTY device. Instead, the line discipline subsystem instantly sends SIGTSTP to the foreground process group.
This helps me, thanks for pointing me back at this great write-up.
Control-C is part of POSIX job control. If a stream (or "cooked" tty) sends a control-C (ASCII End-Of-Text or ETX), the foreground process will be sent a SIGINT signal. If that signal is not handled, the default action is to terminate the process (SIGTERM).
Control-D is just another control character and not part of POSIX job control, but in the "cooked" case above, it will be interpreted as EOF and the process doing the "read" will receive that.
This actually doesn't seem that hard. In both, you are telling the computer, not the target program, something. One is to signal the running program you want to interrupt it. The other is to close the input to the program, as you are done giving it data.