Most programs will fail, to some degree, if somebody closes the stdio files. Malicious users can also cause a program to fail by setting an absurdly-small memory quota (ulimit), or in numerous other sabotage-ey ways. Yes, you can forbid your users from doing so IMHO.
If you like, you can try to insulate your program from this particular sabotage just by continuing to open() /dev/null until you get a 3 (or larger), then close that one, then go on to your main function. Of course, your sabot-wielding user could still use the shell to open all possible file descriptors on you, so that your first open() would fail. So, handle that too? How, exactly? But then, assuming your program needs files, how can it function when all slots are filled? The Unixes I first used could only open 20 files at once. If you needed #21, well, close one of the others first.
What's the justification for this user to close stdout? He's saying "you don't GET a stdout", which is not at all the same as "you don't NEED a stdout." He's changing the implicit contract the program was written against.
Just how far do you go to try to make your program work in a hostile environment? Better to just say to your users "don't do stupid crap and you won't have stupid problems." Probably in a nicer way than that!
There are times and places for processes that DON'T have stdio, but such would be few and far between, and would probably use no libraries of standard code, or even standard idioms like printf("message").
So, to answer the question: Don't. Let the malicious user experience the natural side-effects of his malice.