That's the right approach. Output goes to standard output, and user facing messages go to standard error. That way output can still be piped or redirected while the program talks to the user, and messages can also be suppressed by redirecting to the null device.
I've always been annoyed by the fact file descriptor 2 is called the "error" stream. Should have been called the "user" stream.