UAP Common Extensions 3.1 Help

Formatting

In the printf.h header you can find various useful printf()-like functions that can write the formatted output directly to an arbitrary stream or buffer, or to memory allocated by an allocator.

With the help of these convenience functions, you do not need the libc snprintf to print your string to a temporary buffer anymore, plus you do not need to worry about too small buffer sizes, because the functions will automatically allocate enough memory to contain the entire formatted string.

#include <cx/printf.h> int cx_fprintf(void *stream, cx_write_func wfc, const char *fmt, ...); int cx_vfprintf(void *stream, cx_write_func wfc, const char *fmt, va_list ap); int cx_bprintf(CxBuffer *buf, const char *fmt, ...);

The cx_fprintf() function uses the stdio snprintf() to prepare a formatted string which is then written to the stream using the write function wfc. The return value is the number of bytes written or a value less than zero when an error occurred. If the resulting string is short enough, no additional memory is allocated on the heap. See the Section about Small Buffer Optimization for more details.

The cx_vfprintf() function is equivalent to cx_fprintf(), except that instead of being called with a variable number of arguments, it is called with an argument list as defined by <stdarg.h>.

The cx_bprintf() function is implemented as macro for cx_fprintf() with the CxBuffer as stream and the cxBufferWriteFunc as write function.

#include <cx/printf.h> cxmutstr cx_asprintf(const char *fmt, ...); cxmutstr cx_asprintf_a(const CxAllocator *allocator, const char *fmt, ...); cxmutstr cx_vasprintf(const char *fmt, va_list ap); cxmutstr cx_vasprintf_a(const CxAllocator *allocator, const char *fmt, va_list ap);

The cx_asprintf() and cx_asprintf_a() functions print the formatted output directly to a freshly allocated string which is then returned from the function. On platforms (or when using allocators) where allocation can fail, the returned string may be empty and the ptr field set to NULL.

The cx_vasprintf() and cx_vasprintf_a() functions are equivalent to cx_asprintf() and cx_asprintf_a(), except that instead of being called with a variable number of arguments, they are called with an argument list as defined by <stdarg.h>.

#include <cx/printf.h> int cx_sprintf(char **str, size_t *len, const char *fmt, ...); int cx_sprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, ...); int cx_sprintf_s(char *buf, size_t *len, char **str, const char *fmt, ...); int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, ...); int cx_vsprintf(char **str, size_t *len, const char *fmt, va_list ap); int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, va_list ap); int cx_vsprintf_s(char *buf, size_t *len, char **str, const char *fmt, ...); int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, va_list ap);

The cx_sprintf() and cx_sprintf_a() functions take a pointer str to a pointer to a pre-allocated buffer, as well as a pointer len to *str's length. If the formatted output would not fit into this buffer, it is reallocated and the new pointer to the buffer and the new length are written back to the variables pointed to by str and len.

The cx_sprintf_s() and cx_sprintf_sa() functions differ from the previous function in that they take the pointer to the pre-allocated buffer in the buf argument and not in the str argument (which in this case is only used for storing the resulting pointer), and always allocate an entirely new buffer when the length is insufficient. This is particularly useful when you want to print the formatted string to a buffer allocated on the stack, but also want the option to switch to heap-allocated memory when necessary.

In other words: when the formatted output fits into the buffer pointed to by buf, buf will be written to *str. Otherwise, the pointer to the freshly allocated buffer is written to *str.

The cx_vsprintf(), cx_vsprintf_a(), cx_vsprintf_s(), and cx_vsprintf_sa() functions are equivalent to cx_sprintf(), cx_sprintf_a(), cx_sprintf_s(), and cx_sprintf_sa(), except that instead of being called with a variable number of arguments, they are called with an argument list as defined by <stdarg.h>.

Small Buffer Optimization

All functions that allocate internal temporary memory use small buffer optimization to avoid a heap allocation if the expected string length is smaller than cx_printf_sbo_size. This size cannot be changed at runtime, but modified by defining the CX_PRINTF_SBO_SIZE macro when building the library.

Last modified: 06 April 2025