Created
November 4, 2010 15:38
-
-
Save unixpickle/662640 to your computer and use it in GitHub Desktop.
create a C string from a format without manually allocating a buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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