The proper answer to that question is that the question would demonstrate a skill that it is bad to have. They are wanting you to demonstrate the ability to write hacker code. They are wanting you to invent your own implementation of things provided already by every C compiler, which is waste of time. They are wanting you to write streamlined code which, by definition, is not readable. The 15 line implementation is probably better if it is more readable. Most projects do not fail because the developers wasted 150 clock cycles. Some do fail because someone wrote unmaintainable code. If you did have to write that, it would need a 15 line comment. So my answer to that would be, show me the performance metrics that defend needing to not use the standard libraries and requiring the most optimal solution. Time is much better spent on design and gathering those performance metrics.
Never forget - you are also interviewing them.
//assuming szA contains "first string" and szB contains "second string"
//and both are null terminated
// iterate over A until you get to null, then iterate over B and add to the end of A
// and then add null termination to A
// WARNING: memory corruption likely if either string is not NULL terminated
// WARNING: memory corruption likely if the storage buffer for A was not allocated large
// enough for A to store all of B's data
// Justification: Performance metric XXX has shown this optimization is needed
for(int i=0; szA[i]!='\0'; i++);
for(int j=0; (j==0)||(szB[j-1]!='\0'); j++) szA[i+j] = szB[j];
*edit, 9/27/2010
After reading some other solutions to this, I think the following is probably the best code answer:
//Posted by Doug in answer below this one
void my_strcat(char * dest, const char * src)
{
while (*dest) ++dest;
while (*dest++ = *src++);
}
But I would follow that up with a safe version of that:
void my_safe_strcat(char * dest, const unsigned int max_size, const char * src)
{
int characters_used=0;
while (*dest) { ++dest; characters_used++; }
while ( (characters_used < (max_size-1) ) && (*dest++ = *src++) ) characters_used++;
*dest = 0; //ensure we end with a null
}
And follow that up with (full answer, which compiler will optimize to be the same as above, along with application which was the real question):
void my_readable_safe_strcat(char * dest, const unsigned int max_size, const char * src)
{
unsigned int characters_used = 0;
while (*dest != '\0')
{
++dest;
characters_used++;
}
while ( (characters_used < (max_size-1) ) && (*dest = *src) )
{
dest++;
src++;
characters_used++;
}
*dest = 0; //ensure we end with a null
}
int _tmain(int argc, _TCHAR* argv[])
{
char szTooShort[15] = "First String";
char szLongEnough[50] = "First String";
char szClean[] = "Second String";
char szDirty[5] = {'f','g','h','i','j'};
my_readable_safe_strcat(szTooShort,15,szClean);
printf("This string should be cut off:\n%s\n\n",szTooShort);
my_readable_safe_strcat(szLongEnough,50,szClean);
printf("This string should be complete:\n%s\n\n",szLongEnough);
my_readable_safe_strcat(szLongEnough,50,szDirty);
printf("This string probably has junk data in it, but shouldn't crash the app:\n%s\n\n",szLongEnough);
}