As usual on embedded systems you have to provide your own getchar() and putchar() routines. SDCC does not know whether the system connects to a serial line with or without handshake, LCD, keyboard or other device. And whether a lf to crlf conversion within putchar() is intended. You'll find examples for serial routines f.e. in sdcc/device/lib.
The default printf()implementation in printf_large.c does not support float (except on ds390). To enable this recompile it with the option -DUSE_FLOATS=1 on the command line. Use --model-large for the mcs51 port, since this uses a lot of memory.
If you're short on memory you might want to use printf_small() instead of printf(). For the mcs51 there additionally are assembly versions printf_tiny() (subset of printf using less than 270 bytes) and printf_fast() and printf_fast_f() (floating-point aware version of printf_fast) which should fit the requirements of many embedded systems (printf_fast() can be customized by unsetting #defines to not support long variables and field widths).