Since injection attacks exploit control sequences in the way the output is interpreted, and since different output formats use different control sequences (think JavaScript versus SQL versus HTML), your sanitization technique needs to reflect where the output is going. If you sanitize for output upon input, you're making an assumption about where that output is going to be sent, which may prove to be incorrect, perhaps due to some future change or some usage case you didn't think fo.
Therefore, as a rule I would suggest sanitizing on output to reflect the specific injection sensitivity for the format you're outputting in.
Note that if you're storing pre-formatted input and the context of the formatting is not available upon output (such as storing HTML for a blog post), you may do some checks upon input, but this is a slightly different scenario than just general escaping.
So again, as a rule escape your output rather than your input, but make exceptions as necessary with the understanding that those exceptions need to be watched with extra scrutiny as you're creating a hole in your app that you need to carefully guard.