There's no reason you can't realize some of these benefits in C. I wrote a program recently that produces a new struct every time the state changes (any function that changes the state is passed the current state struct by value and returns a new state struct.) While part of the state is a multi-gigabyte memory allocation, this is represented as a pointer, so copying it from state to state is very cheap. This means that all of the structs point to the same chunk of memory, so only one of them can be considered valid at a time. I found that this approach made it very easy to keep track of what state my program was in. It greatly simplified error handling because I could just discard a failed update rather than trying to unwind it.
You're correct. I've been writing C lately with functional concepts in mind and noticed an improvement in cleanliness with state and style. I'd definitely recommend trying it to other C developers.