forked from b-k/21st-Century-Examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasprintf.c
56 lines (48 loc) · 1.38 KB
/
asprintf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/* Compile with:
CFLAGS="-g -Wall -std=gnu11 -O3 -DTest_asprintf" make asprintf
*/
#ifndef HAVE_ASPRINTF
#include <stdio.h> //vsnprintf
#include <stdlib.h> //malloc
#include <stdarg.h> //va_start et al
/* The declaration, to put into a .h file. The __attribute__ tells the compiler to check printf-style type-compliance.
It's not C standard, but a lot of compilers support it. Just remove it if yours doesn't. */
int asprintf(char **str, char* fmt, ...) __attribute__ ((format (printf,2,3)));
int asprintf(char **str, char* fmt, ...){
va_list argp;
va_start(argp, fmt);
char one_char[1];
int len = vsnprintf(one_char, 1, fmt, argp);
if (len < 1){
fprintf(stderr, "An encoding error occurred. Setting the input pointer to NULL.\n");
*str = NULL;
va_end(argp);
return len;
}
va_end(argp);
*str = malloc(len+1);
if (!str) {
fprintf(stderr, "Couldn't allocate %i bytes.\n", len+1);
return -1;
}
va_start(argp, fmt);
vsnprintf(*str, len+1, fmt, argp);
va_end(argp);
return len;
}
#endif
#ifdef Test_asprintf
int main(){
char *s;
asprintf(&s, "hello, %s.", "—Reader—");
printf("%s\n", s);
free(s);
asprintf(&s, "%c", '\0');
printf("blank string: [%s]\n", s);
free(s);
int i = 0;
asprintf(&s, "%i", i++);
printf("Zero: %s\n", s);
free(s);
}
#endif