What kinda bugs me is that whenever people go to teach C, they make out like it _has_ to be a low-level exercise, as if writing in C suddenly means you can't use abstract data types or object-oriented style or name your functions properly or have Unicode support.
For example, people teach libc string APIs like scanf() and strtok(), which should almost never be used. (See http://vsftpd.beasts.org/IMPLEMENTATION for one take.) Instead, use http://git.gnome.org/browse/glib/tree/glib/gstring.h or write your own like http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-string....
If you're going to display user-visible text, you are pretty much required to link to GLib or another Unicode library, since libc doesn't have what you need (unless you want to use the old pre-unicode multi-encoding insanity).
Don't use fgets() and other pain like that, use g_file_get_contents() perhaps, or another library. (g_file_get_contents is in http://developer.gnome.org/glib/stable/glib-File-Utilities.h...)
You need help from a library other than libc to deal with portability, internationalization, security, and general sanity.
Maybe more importantly, a library will show you examples that in C you can still use all the good design principles you'd use in a higher-level language.
I told someone to "use a string class" in C recently for example, and they said "C doesn't have classes" - this is confusing syntax with concepts.
C requires more typing and more worrying about memory management, that's all. It doesn't mean that all the best practices you know can be tossed.
There's a whole lot to be said about how to write large, maintainable codebases in C, and it can even be done. It's not something I would or do choose to do these days, but it can be done.
One other thought, two of the highest-profile C codebases, the Linux kernel and the C library, have extremely weird requirements that simply do not apply to most regular programs. However, a lot of people working in C or writing about C have experience with those codebases, and it shows.