4 ms·
I use this: char* scatn(char* ss, …); #define scat(args...) scatn(args, 0) char* scatn(char* ss, ...) { char *s; char *new;
by sambeau 15y ago
I use this:
char* scatn(char* ss, …);
#define scat(args...) scatn(args, 0)
char* scatn(char* ss, ...)
{
char *s;
char *new;
size_t len;
size_t n;
va_list ap;
/* first find the lengths of the strings */
va_start(ap, ss);
s = ss;
len = 0;
while(s != 0){
len = len + strlen(s);
s=va_arg(ap, char *);
}
va_end(ap);
/* make a buffer big enough for all strings + '\0" */
new = (char *) malloc(sizeof(char) * (len + 1));
if(new == NULL){
perror("Out of memory");
exit(EXIT_FAILURE);
}
/* copy the strings into the buffer */
va_start(ap, ss);
s = ss;
n = 0;
while(s != 0){
len = strlen(s);
memcpy(new+n,s,len);
n = n + len;
s=va_arg(ap, char *);
}
va_end(ap);
/* terminate the string */
new[n]='\0';
/* return the string: remember to free it! */
return new;
}
use like this:
s = scat("hello","hacker","news");
:
free(s);
I did have a version with only one loop and realloc but it turned out to be twice as quicker to go through each string twice. I have no idea why :)
- koenigdavidmj 15y agoDude. Factor out the strlen(3) calls. My eyes!
- sambeau 15y ago(you had me questioning my sanity for a moment there) short answer: I did. It got slower! They're not doing what you think they are. Each string only gets measured twice. To factor them out I will need to start allocating extra arrays just to keep their values: the extra malloc and free is slower than measuring the strings twice. I also tried a Reallocing version that didn't need them but it was twice as slow. I use this code for composing text in places where speed isn't my first concern; especially error messages. But its plenty fast enough for 90% of what anyone would need. You'd rarely be concating more than 6 things together. note: it's really hard to talk about pointers on HN as you can't type an asterisk without a code block, but it's: while(s != 0) not while(*s != 0)
- apaprocki 15y agoIf you're talking about inputs that aren't arbitrarily huge, you should try measuring performance using alloca instead of malloc.
- abecedarius 15y agoIt's the second strlen plus the memcpy right after it that I would consider replacing (with a loop that fuses both). (Though since you say it doesn't matter, never mind...)
- tedunangst 15y agoMay as well use asprintf if that's the kind of thing you want.
- dchest 15y agoIf len overflows and wraps (i.e. the sum of string lengths is > SIZE_MAX-1), you'll allocate less memory than is required and memcpy will write outside of buffer bounds.
- tedunangst 15y agoWhile that may be possible in some segmented systems, it's worth noting that on just about any modern system having a set of strings bigger than all available memory is unlikely.