I'm probably dumb but one of things that bugs me with various libraries is when someone has made the decision to do something high level at a low level. For example, localizing inside sprintf,
An another example might be an unzip library (read a zip file). Ideally the library should be small IMO. The simplest might you you pass it a bucket of bytes. If you want to make it flexible then you pass it some abstract interface (or 1-2 functions + void* userdata) so you can supply a "read(byteOffset, length)". You can then provide, outside of the library, streamed files, stream networking, etc...
But, bad libraries (bad IMO) will instead provide like 12 overrides "unzip(void* bytes), unzip(const char* filename), unzip(socket), unzip(url)" and end up including the world in their library. This kind of "try to do everything" is extremely common in npm libraries :( I don't need your library to include command line parsing! If you want to make a tool, make a library, then make a separate tool that uses that library. Keep the 2 separated so users of the library don't need dependencies that only the tool needs. (probably the most common npm example but there are lots of others)
Really surprised something as low-level as sprintf needs locale. Even streams I'd expect maybe a Date object would but not the stream itself.