Interview Question-Concatenation of two lines without using strcat in C

I recently attended an interview where they asked me to write a C program to combine two lines without using strcat() , strlen() and strcmp() , and this function should not exceed two (2) lines.

I know how to concatenate two strings without using strcat() . But my method has about 15 lines. I do not know how to write it in two lines.

+6
c string
source share
10 answers

I expect them to want something like this:

 void mystrcat(char * dest, const char * src) { //advance dest until we find the terminating null while (*dest) ++dest; //copy src to dest including terminating null, until we hit the end of src //Edit: originally this: //for (; *dest = *src, *src; ++dest, ++src); //...which is the same as this for (; *dest = *src; ++dest, ++src); } 

It does not return the end of the concatenated string, like a real strcat , but this does not seem to be required.

I don’t necessarily know if this question is a good question for an interview - it shows that you can adjust the code, and that you know what strcat does, but about that.

Edit: as aib writes, statement

 while (*dest++ = *src++); 

... perhaps the more common way to write a second loop (instead of using for ).

+20
source share

Given that the task was to combine the two lines, rather than duplicate strcat , I would go with the simple possibility of creating a completely new line, which is a combination of the two.

 char buffer[REASONABLE_MAX] = {0}; snprintf(buffer, REASONABLE_MAX - 1, "%s%s", string1, string2); 
+17
source share

The correct answer to this question is that the question will demonstrate a skill that is bad to have. They want you to demonstrate the ability to write hacker code. They want you to invent your own implementation of the things provided by every C compiler, which is a waste of time. They want you to write streamlined code that by definition is not readable. A 15-line implementation is probably better if it is more readable. Most projects fail, because the developers spent 150 clock cycles. Some of them fail because someone writes unsupported code. If you need to write this, he will need a 15-line comment. So, my answer to this is, show me the performance indicators that protect, so as not to use standard libraries and require the most optimal solution. Time is much better spent designing and collecting these performance indicators.

Never forget - you also interviewed 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 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, I think that probably the best answer to the code:

  //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 do it with a safe version:

  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 this (full answer, which the compiler will optimize the same as above, along with the 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); } 
+6
source share

Two lines? Bwah ...

 void another_strcat(char* str1, const char* str2) { strcpy(strchr(str1, '\0'), str2); } 

EDIT: I am very upset that people are so against strcpy and strchr. Waah! So, I thought I would play in the spirit of the rules:

 char thing(char* p, const char* s) { return *p ? thing(&p[1], s) : *s ? (*p++ = *s++, thing(p, s)) : *p = '\0'; } 

I still can't figure out how someone will take 2 whole lines; -P.

+5
source share

I tested this bit in VS2008 and it worked fine.

 void NewStrCat(char* dest, const char* src) { while (*dest) ++dest; while (*dest++ = *src++); } 
+3
source share

Any function can be made to fit on one line by simply deleting all \n .

However, I think you are looking for this answer:

 #include <stdlib.h> #include <stdio.h> #include <string.h> int main(void) { char string1[32] = "Hello"; char string2[] = ", World!"; char *dst = string1 + strlen(string1); char *src = string2; while (*dst++ = *src++); //single statement printf("\"%s\"\n", string1); return EXIT_SUCCESS; } 

The explanation is quite simple:

src++ returns a pointer to the current character, which is copied before increasing it to the next. * casts this pointer, and a similar expression on LHS copies it to dst . The result of the entire expression = is the character that was copied, so a simple while terminates it until it encounters and copied \0 .

But:

strcat() easier to read and possibly much faster. Any other solution is possible only when strcat() not available. (Or, when you're in an interview, apparently.) And replace strcat() above with strncat() if you are really not sure if the strncat() string is big enough.

Edit: I missed the strlen() part that was forbidden. Here is the function of two operators:

 void my_strcat(char * restrict dst, const char * restrict src) { while (*dst) ++dst; //move dst to the end of the string while (*dst++ = *src++); //copy src to dst } 

Note that the standard strcat() function returns the original dst value.

+2
source share

One line:

 sprintf(string1, "%s%s", string1, string2); 

(Note that this may possibly cause undefined behavior.)

Adding

The ISO C99 standard states that:
If copying occurs between overlapping objects, the behavior is undefined.

In doing so, the above code is likely to work correctly. It works with MS VC 2010.

+1
source share
 void StringCatenation(char *str1,char *str2) { int len1,i=0; for(len1=0;*(str1+len1);len1++); do{ str1[len1+i]=str2[i]; i++; } while(*(str2+i); } 
0
source share

I have the feeling that such questions are designed to address issues, not choices. It is easier to exclude candidates for them based on such intricate questions, rather than choose candidates by asking them more real world questions. Just a saying from me, since I am also looking for work and come across such questions and answered many of them thanks to SO!

0
source share
 void my_strcat(char* dest, const char* src) { while (*dest) ++dest; while (*dest++ = *src++); *dest = '\0'; } 

The target line must end with NULL termination.

0
source share

All Articles