【问题标题】:Concatenating two strings in C在C中连接两个字符串
【发布时间】:2014-10-23 14:45:33
【问题描述】:

所以我必须创建一个函数来连接 C 中的两个字符串;该函数通过连接 str1 和 str2 创建一个新字符串。该函数必须调用 malloc() 或 calloc() 为新字符串分配内存。函数返回新字符串。

在主测试函数中执行以下对 printf() 的调用后: printf ( "%s\n", myStrcat( "Hello", "world!" ));屏幕上的打印输出必须是 Helloworld!

到目前为止,这是我的代码;我不太明白为什么它不起作用。它没有做任何事情...它编译并运行,但没有显示任何内容。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *my_strcat( const char * const str1, const char * const str2);

int main()
{
    printf("%s", my_strcat("Hello", "World")); // test function. Output of print statement    is supposed to be HelloWorld
}

char *my_strcat( const char * const str1, const char * const str2)
{

    char *temp1 = str1; // initializing a pointer to the first string
    char *temp2 = str2; // initializing a pointer to the second string

    // dynamically allocating memory for concatenated string = length of string 1 + length of string 2 + 1 for null indicator thing.
    char *final_string = (char*)malloc (strlen(str1) + strlen(str2) + 1);

    while (*temp1 != '\0') //while loop to loop through first string. goes as long as temp1  does not hit the end of the string
    {
        *final_string = *temp1; // sets each successive element of final string to equal each successive element of temp1
        temp1++; // increments address of temp1 so it can feed a new element at a new address
        final_string++; // increments address of final string so it can accept a new element at a new address
    }
    while (*temp2 != '\0') // same as above, except for string 2.
    {
        *final_string = *temp2;
        temp2++;
        final_string++;
    }

    *final_string = '\0'; // adds the null terminator thing to signify a string
    return final_string; //returns the final string.
}

【问题讨论】:

  • 不要在 C 中转换 malloc
  • 在此处发布时请正确缩进您的代码。
  • *final_string = '\0'; return final_string;

标签: c string


【解决方案1】:

您正在返回 final_string,但它在您的算法过程中被递增以指向空终止符 - 而不是字符串的开头。

您需要将分配更改为:

char *final_string_return = malloc(strlen(str1) + strlen(str2) + 1);
char *final_string = final_string_return;

然后是:

return final_string_return;

【讨论】:

    【解决方案2】:

    您应该将malloc 的结果存储在另一个变量中(您应该始终针对失败进行测试):

    char *result_string = malloc (strlen(str1) + strlen(str2) + 1); 
    if (!result_string) { perror("malloc"); exit(EXIT_FAILURE); };
    final_string = result_string;
    

    最后归还

    return result_string;
    

    所以final_string 这个名字是不幸的;让它也许current_pointer

    顺便说一句,您的函数仅适用于 调用者 应该释放其结果的约定。您应该记录该约定(至少在 cmets 中)。特别是在您的 main 函数中

    printf("%s", my_strcat("Hello", "World"));
    

    memory leak(你永远不会freemy_strcat 调用的结果,但你应该这样做)。

    请养成使用警告和调试信息进行编译的习惯(例如gcc -Wall -Wextra -gGCC),并学习如何使用调试器(gdb),因为您可以在调试器中逐步执行您的程序。也可以使用 valgrind 来检测 - 通过测试 - 一些内存泄漏。

    【讨论】:

    • 感谢您的建议!我会尝试对其中一些事情进行自我教育;在这一点上,以我的知识水平,你的最后一段比我头上几英里。
    【解决方案3】:
    int main( void )
    {
        char * concatStr = my_strcat("Hello", "World");
    
        printf("%s", concatStr); // test function. 
        // Output of print statement    is supposed to be HelloWorld
        free( concatStr ); // note this is safe, even if my_strcat() returns NULL
        return(0);
    }
    
    char *my_strcat( const char * const str1, const char * const str2)
    {
    
    
        // dynamically allocating memory for concatenated string 
        // = length of string 1 + length of string 2 + 1 for null indicator thing.
        // and sets all bytes to '\0'
        char *final_string = calloc ((strlen(str1) + strlen(str2) + 1), 1);
        if( NULL == final_string )
        { // then calloc() failed
            return( NULL );
        }
        // implied else, calloc() successful
    
        strcpy( final_string, str1 );
        strcat( final_string, str2 );
    
        return( final_string ); // note: caller must invoke free() 
                                //       to avoid memory leak.
    }
    

    【讨论】:

      【解决方案4】:

      你总是可以使用sprintf

      char* my_strcat(const char* const s1, const char* const s2)
      {
          char *dst = malloc(strlen(s1) + strlen(s2) + 1);
          if (dst == NULL)
          {
            return NULL;
          }
          sprintf(dst, "%s%s", s1, s2);
          return dst;
      }
      

      【讨论】:

        【解决方案5】:

        final_string 指向目标字符串的结尾。

        以下代码返回最终字符串:

        return (final_string-strlen(str1)-strlen(str2)-1); //returns the final string.
        

        【讨论】:

        • final_string 的地址减去 str1 的长度减去 str2 的长度减去 1 将指向 la-la 土地,在堆栈上的某处
        • 你的意思是final_string的地址会小于str1的长度加上str2的长度加1?我忽略了这个问题...
        猜你喜欢
        • 1970-01-01
        • 2012-01-17
        • 1970-01-01
        • 2013-08-30
        • 2019-11-06
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        • 2013-11-05
        相关资源
        最近更新 更多