There's no such thing as an elegant program in C, unless you count exceedingly trivial examples. The advantages of OO become inherently apparent as soon as you try to do even something basic, like strings. If you can't see why
std::string is so much better than C strings in every possible way, then you need to take a much closer look. I'll give you a head start by demonstrating some of the massive benefits:
The Standard string class handles all it's own memory- specifically, you are guaranteed to never, ever leak a
std::string. This is way ahead of a C string.
The Standard string class offers O(1) size. C strings only offer O(n) size.
The Standard string class does not require NULL termination. This solves many off-by-one errors that exist in C string code.
The Standard string class cannot have it's memory freed by another user. It cannot have the memory be reallocated by another user. The ownership is explicit and enforced by the compiler. If you pass a
char* to a function, they could attempt to free it when you already do that, or such things.
The Standard string class is smarter than you. Specifically, it can do things like small-string optimization without having to change your user code. If you wanted to implement SSO, you would have to refactor every single bit of code that uses strings. When
std::string implements SSO, you don't even notice.
The Standard string class is generic. The function for sorting a vector of integers is just the same as the one for sorting a vector of strings, and it's faster than C's
The Standard string class grows itself when it needs to. No more
MAGIC_BUFFER_SIZE codes which overflow and are vulnerable, and you can guarantee that your library implementer spent an awful long time, much longer than you could ever justify spending, profiling and determining the optimum way in which to grow.
When you compile in Debug mode, the Standard string class will error-check your iterators and indexes, and when you request it, indexes in normal code too. Will a
char do this for you? I doubt it.
std::string is faster, safer, and more maintainable than C-strings. Other classes offer very similar reasons to be vastly superior in every possible fashion. What more do you want from object-orientation other than superior speed, correctness, and ease of maintenance?
Therefore, pretty much by definition, any C++ program that is equivalent to your C program but uses OO to handle strings is inherently and vastly superior to your C program.
The problem that you exhibt is most easily picked up on here:
I believe to be a much more elegant program.
You believe? Awesome. Why don't you actually go back and check? Because I think you'll find that actually, said programs are buggy and slow, and would be greatly improved by a judicious application of solid object orientation. Your subjective feelings arise for reasons that have nothing to do with the actual quality of the program.
You need to recognize that the objective qualities of speed, maintenance, and correctness of a program has absolutely nothing to do with your subjective opinion of whether or not it's elegant.
And you know what? Not every problem is best approached by OO. There's a reason that languages like C# have lambdas and generics, and it's because inheritance isn't a Swiss army knife. It's just one tool, and there are others which serve certain purposes better. It is, however, a remarkably effective tool for many situations, best used for structuring programs and modules.