Skip to content

Instantly share code, notes, and snippets.

@markusfisch
Created July 28, 2014 11:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markusfisch/61e6129781e93260f6fa to your computer and use it in GitHub Desktop.
Save markusfisch/61e6129781e93260f6fa to your computer and use it in GitHub Desktop.
Format strings into a expanding buffer

sbprintf

Format strings into a expanding buffer.

Sample

struct sbprintf_string_buffer sb = { NULL, NULL, 0 };

sbprintf( &sb, "%d: %s\n", 1, "one" );
sbprintf( &sb, "%d: %s\n", 2, "two" );
sbprintf( &sb, "%d: %s\n", 3, "tree" );
sbprintf( &sb, "%d: %s\n", 4, "four" );
sbprintf( &sb, "%d: %s\n", 5, "five" );

printf( "%s", sb.base );
free( sb.base );

Strategies

You may either call sbprintf() with a NULL'ed sbprintf_string_buffer structure (see sample above) and have it (re)allocate memory on every call or you may allocate a buffer of reasonable size beforehand:

struct sbprintf_string_buffer sb;

sb.length = 1024;
sb.base = sb.cursor = malloc( sb.length );

The first option is more memory efficient, the latter may perform better according on how many additional realloc()'s are required.

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "sbprintf.h"
/**
* Format data and automatically allocate memory to be of sufficient length
*
* @param sb - string buffer structure
* @param format - printf format description
* @param ... - arguments
*/
int sbprintf( struct sbprintf_string_buffer *sb, const char *format, ... )
{
while( sb )
{
va_list ap;
int pos = sb->cursor-sb->base;
int left = sb->length-pos;
int written;
char *p;
va_start( ap, format );
written = vsnprintf( sb->cursor, left, format, ap );
va_end( ap );
if( written < 0 )
break;
if( sb->cursor &&
written < left )
{
sb->cursor += written;
return written;
}
left = pos+written+1;
if( !(p = (char *)realloc( sb->base, left )) )
break;
sb->base = p;
sb->cursor = sb->base+pos;
sb->length = left;
}
return -1;
}
#ifndef _sbprintf_h_
#define _sbprintf_h_
struct sbprintf_string_buffer
{
char *base;
char *cursor;
int length;
};
int sbprintf( struct sbprintf_string_buffer *, const char *, ... );
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment