Skip to content

Instantly share code, notes, and snippets.

@unixpickle
Created November 4, 2010 15:38
Show Gist options
  • Save unixpickle/662640 to your computer and use it in GitHub Desktop.
Save unixpickle/662640 to your computer and use it in GitHub Desktop.
create a C string from a format without manually allocating a buffer
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
int strappend (char ** buff, int alloclen, const char * nstring) {
int slen = strlen(buff[0]);
int slen2 = strlen(nstring);
char * newbuff = (char *)malloc(slen + slen2 + 2);
memset(newbuff, 0, slen+slen2+2);
memcpy(newbuff, buff[0], slen);
memcpy(&newbuff[slen], nstring, slen2);
free(buff[0]);
buff[0] = newbuff;
return (slen + slen2 + 2);
}
char * makestring (char * fmt, ...) {
va_list listPointer;
int count = 0, len = strlen(fmt);
int i;
for (i = 0; i < len; i++) {
if (fmt[i] == '%') {
if (i + 1 < len) {
if (fmt[i+1] != '%') {
count += 1;
}
}
}
}
va_start (listPointer, fmt);
// now we can calculate total length
char * mstr = (char *)malloc(1);
mstr[0] = 0;
int alloclen = 1;
for (i = 0; i < len; i++) {
char c = fmt[i];
if (i + 1 < len && c == '%') {
char nc = fmt[++i];
if (nc == 's') {
// append string
const char * ms = va_arg (listPointer, const char*);
alloclen = strappend(&mstr, alloclen, ms);
} else if (nc == 'd') {
int ic = va_arg (listPointer, int);
char ms[20];
sprintf(ms, "%d", ic);
alloclen = strappend(&mstr, alloclen, ms);
} else if (nc == 'p') {
void * ic = va_arg (listPointer, void*);
char ms[20];
sprintf(ms, "%p", ic);
alloclen = strappend(&mstr, alloclen, ms);
} else if (nc == 'f') {
double ic = va_arg (listPointer, double);
char ms[20];
sprintf(ms, "%lf", ic);
alloclen = strappend(&mstr, alloclen, ms);
} else if (nc == '%') {
alloclen = strappend(&mstr, alloclen, "%");
}
} else {
char str[2];
sprintf(str, "%c", c);
alloclen = strappend(&mstr, alloclen, str);
}
}
va_end (listPointer);
return mstr;
}
int main (int argc, char * argv[]) {
char * str = makestring("hello %s!\n%d%% complete\n", "world!", 100);
printf("%s", str);
free(str);
str = makestring("pi = %f\n", 3.141592);
printf("%s", str);
free(str);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment