Revert
The git revert command is designed to do exactly this.
git revert <hash for C>
This will create a new commit which reverses the change in C.
Rewrite History
You can also rewrite history. This is not generally recommended, and should only be used if you have a good reason to actually remove a commit from history (say, if it contains a password or something).
git rebase -i <hash for B>
In the editor, just delete the line with the hash for C. The usual caveats apply if you have already pushed.
Non-interactive
Technically, all of these options involve some kind of merge resolution which means they cannot truly be non-interactive. The only difference is the resulting history. With git revert you get a history that looks like this:
A -> B -> C -> D -> E
^
+--- reverts C
With git rebase, you end up with a history that looks like this:
A -> B -----------> E
You can of course just do git rebase --onto B C, instead of git rebase -i, but this is still an interactive process because you have to manually resolve any merge conflicts that can’t be automatically resolved by the merge strategy.