面试问题 - 在C中不使用strcat连接两个字符串

Ram*_*Ram 6 c string

最近我参加了一个访谈,他们要我写一个C程序连接两个字符串不使用strcat(),strlen()并且strcmp()和功能不应超过两(2)线.

我知道如何在不使用的情况下连接两个字符串strcat().但我的方法有近15行.我不知道怎么写两行.

Dou*_*oug 20

我希望他们想要这样的东西:

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);
}
Run Code Online (Sandbox Code Playgroud)

它不像真实一样返回连接字符串的结尾strcat,但似乎并不需要.

我不一定知道这种事情是否是一个很好的面试问题 - 它表明你可以简洁地编码,而且你知道它是strcat做什么的,但那是关于它的.

编辑:正如aib所写,声明

while (*dest++ = *src++);
Run Code Online (Sandbox Code Playgroud)

...也许是编写第二个循环(而不是使用for)的更常规方式.

  • 我认为能够认识到任务的微不足道以及如何简洁地表达它是一项重要的工作技能.我见过很多傻瓜写20-50行函数来执行与strcat相同的任务. (3认同)

tor*_*rak 17

鉴于任务是连接两个字符串,而不是创建副本strcat,我会选择创建一个全新字符串的简单选项,该字符串是两者的组合.

char buffer[REASONABLE_MAX] = {0};
snprintf(buffer, REASONABLE_MAX - 1, "%s%s", string1, string2);
Run Code Online (Sandbox Code Playgroud)

  • +1为聪明和使用`snprintf`.:-) (2认同)

Pat*_*ckV 6

这个问题的正确答案是,这个问题会证明一项技能很难实现.他们希望您展示编写黑客代码的能力.他们希望你发明自己的每个C编译器提供的东西实现,这是浪费时间.他们希望您编写简化的代码,根据定义,这些代码是不可读的.如果它更具可读性,那么15行实现可能会更好.大多数项目都没有失败,因为开发人员浪费了150个时钟周期.有些人因为有人编写了不可维护的代码而失败了.如果你必须写那个,那就需要15行评论.所以我对此的回答是,向我展示保护不需要使用标准库并需要最佳解决方案的性能指标.

永远不要忘记 - 你也在采访他们.

 //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];
Run Code Online (Sandbox Code Playgroud)

*编辑,2010年9月27日

在阅读了其他一些解决方案之后,我认为以下可能是最好的代码答案:

 //Posted by Doug in answer below this one
 void my_strcat(char * dest, const char * src)
 {    
      while (*dest) ++dest;    
      while (*dest++ = *src++);     
 }
Run Code Online (Sandbox Code Playgroud)

但我会用一个安全版本来跟进:

 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
 }
Run Code Online (Sandbox Code Playgroud)

然后跟着(完整答案,哪个编译器将优化与上面相同,以及应用程序是真正的问题):

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);

}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个面试问题.他们希望看到你在压力下如何创造性地思考,而不是告诉你如何编写代码.我有采访者问我燃烧绳问题,但我保证点燃一根绳子不会成为我工作描述的一部分. (2认同)
  • 如果这是一个现实生活中的问题,你就完全正确了,但事实并非如此,这是一次采访中的智力练习.这样的问题旨在深入了解候选人的创造性思维过程.拒绝回答所述的谜题除了明显缺乏社交技巧外,对面试官没有任何帮助.当面试官要求你估计747的重量时,"正确"的答案是"在维基百科上查找",但这也保证不会给面试官留下深刻的印象. (2认同)

Ton*_*roy 5

两条线?Bwah ...

void another_strcat(char* str1, const char* str2)
{
    strcpy(strchr(str1, '\0'), str2);
}
Run Code Online (Sandbox Code Playgroud)

编辑:我非常沮丧,人们如此反对strcpy和strchr.Waah!所以,我以为我会遵守规则的精神:

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

我仍然无法理解任何人如何采取2条整线;-P.