"Code never lies, comments sometimes do." ~Ron Jeffries

Concatenating an Arbitrary Number of Strings

Today’s order of business is to create a function that can accept an arbitrary number of string and concatenate all of them together – and to do so without the use of any libraries outside of stdarg.h

So a good start seems to be making my own implementation of strcat() to accept two strings:

const char* concat( char* dest, char* source ){
	int destEnd;
	int i;
	
	for( destEnd = 0; dest[ destEnd ]; destEnd++ );
	
	for( i = 0; source[i]; dest[ destEnd++ ] = source[ i++ ]);
	dest[ destEnd ] = '\0';
	
	return dest;
}

Simple as could be – find the null byte of the destination string to overwrite and add on the rest of the characters from the source string until the source’s null is encountered. Finally tack on a terminator to the destination. Easy enough.

Now, of course, we need to start work on a function that can actually handle an arbitrary number of arguments. The concat function makes this easier:

#include <stdarg.h>

const char* nstrcat( char* dest, ... ){	
	char* curArg;
	
	va_list argList;
	va_start(argList, dest);

	for( curArg = va_arg( argList, char* ); *curArg; curArg = va_arg( argList, char* )){
		concat( dest, curArg );
	}
	
	va_end(argList);
	return dest;
}

Well that looked fine to me, but the segmentation faults disagreed. Running it through a debugger I found the segfaults would occur as soon as we got to here after concatenating the last string meant for concatenation:

for( curArg = va_arg( argList, char* ); *curArg; curArg = va_arg( argList, char* ))

I neglected to consider that curArg may actually be null, not just a string containing a null byte. That I had, up until now, been using 0 to terminate my sequence of arguments made this seem like a reasonable cause, and indeed I found it was so when the segfaults disappeared after swapping 0 for “\0” instead. So with one small fix nstrcat() can now be terminated by a null pointer or a null byte, and all is well:

#include <stdarg.h>

const char* concat( char* dest, char* source ){
	int destEnd;
	int i;
	
	for( destEnd = 0; dest[ destEnd ]; destEnd++ );
	
	for( i = 0; source[i]; dest[ destEnd++ ] = source[ i++ ]);
	
	dest[ destEnd ] = '\0';
	
	return dest;
}

const char* nstrcat( char* dest, ... ){	
	char* curArg;
	
	va_list argList;
	va_start(argList, dest);

	for( curArg = va_arg( argList, char* ); curArg && *curArg; curArg = va_arg( argList, char* )){
		concat( dest, curArg );
	}
	
	va_end(argList);
	return dest;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s