"Lumping together function pointers that operate on the same data structure is essentially object-oriented programming" is unbelievably contentious regardless of which of the various definitions of OOP you follow.
Some of the more exotic features of what people call "OOP", like polymorphism, take a bit more care and feeding to pull off in straight C. They are most certainly possible, that being said.
Unwind "OOP" to "working with objects that contain data and methods together," and structs with function pointers fit the bill. I've had people stand in my face and practically shout that C++ is object-oriented and C isn't, and one refused to believe or admit that C++ basically compiles down to C in the end.
C++ 'basically compiles down to C' for some constructs more than others (exceptions, RTTI, multiple inheritance goop) but if the C it compiles to is dark, arcane, unreadable crap, then this is no more illuminating than the truism that C++ basically compiles down to assembly language.
Neither is object-oriented, except C++ allows you to easily work with objects unlike C, where you have to reinvent them.
It is easy for me not to pick C if I need more abstraction than a struct with pointers to functions can provide.
And thus the discussion devolves into a pissing contest over whose programming language is the most object oriented...
Look, one can reasonable agree to disagree on the definition of 'object-oriented', but I don't see how you can seriously state that C++ is not object-oriented. According to the most broadly accepted superset of what constitutes 'object-oriented', C++ is object-oriented (or rather, can be used in such a way).
But what's the difference between foo->doshit() and doshit(&foo)? Those people still don't get stuff like data orientation, etc. but are shouting out loud how evil OO is and how they killed that dragon ;)