【问题标题】:Chaining 2 Strings in C在 C 中链接 2 个字符串
【发布时间】:2018-04-30 16:50:57
【问题描述】:

我想在 C 中链接 2 个字符串。我使用的函数称为 concat() 首先我定义了这样的东西并且它起作用了

char* concat(const char *s1, const char *s2)
{
    char* result = malloc (15);  
    int lengh1 =  simple_strlen (s1);
    int lengh2 =  simple_strlen (s2);
    int i=0,j;
    for ( i = 0 ;i < lengh1;i++){
        if (i!=lengh1-1)
            result[i]=s1[i];
        else{
            result[i]=s1[i];
            for ( j=i+1 ; j< lengh1+lengh2;j++){
                    result[j] = s2[j-i-1];
            }
        }
    }

return result;
} 

但是后来我被要求在没有 malloc() 的情况下这样做,所以我定义了这样的内容:

char* concat( char *result, const char *s2)
{  
    int lengh1 =  simple_strlen (result);
    int lengh2 =  simple_strlen (s2);
    int i=0;
    for ( i = 0 ;i < lengh2;i++){   
            result[i+lengh1]=s2[i];
    } 
    return result;
}

但它有分段错误

example:



   int main(int argc , char* argv[], char* envp[])
   {
          printf(concat( "hello", "world"));/*output expected "helloworld"*/

        return 0;

   }   

【问题讨论】:

  • 请为您的第二个示例显示minimal reproducible example。这个函数是怎么调用的?
  • 我假设 result 没有初始化为指向任何东西,或者它指向的地方不足以存储您的连接字符串。但我们无法确定,因为您没有提供 MCVE。
  • 你需要回顾一下内存和字符串。您的第二种方法会导致错误,因为您无法在“结果”结束后使用内存。您的问题可能定义不明确,因为虽然您可以说“不要使用 malloc”,但您必须有一些地方来放置新字符串。
  • @OldProgrammer 示例已添加
  • 您的“结果”字符串没有足够的额外内存来容纳“s2”字符串中的字符。

标签: c string segmentation-fault


【解决方案1】:

您的代码中存在多个问题:

  • malloc 版本中,为目标字符串分配的空间被硬编码为15,而不是计算为lengh1 + lengh2 + 1,为字符串和结尾的空字节提供了足够的空间。
  • 在两个版本中,您都没有在目标字符串的末尾设置空终止符。
  • 在没有malloc 的版本中,您必须提供足够大的数组作为concat() 的目标。不能修改字符串常量。一个简单的解决方案是将目标缓冲区和源字符串作为单独的参数传递。

以下是修改后的版本:

char *concat(const char *s1, const char *s2) {
    int length1 = simple_strlen(s1);
    int length2 = simple_strlen(s2);
    char *result = malloc(length1 + length2 + 1);
    int i, j;
    for (i = 0; i < length1; i++) {
        result[i] = s1[i];
    }
    for (i = 0; i < length2; i++) {
        result[length1 + i] = s2[1];
    }
    result[length1 + length2] = '\0';
    return result;
}

没有malloc()

#include <string.h>

char *concat(char *dest, const char *s1, const char *s2) {
    char *p = dest;
    while (*s1)
        *p++ = *s1++;
    while (*s2)
        *p++ = *s2++;
    *p = '\0';
    return dest;
}

int main() {
    char buf[100];
    /* output expected "helloworld" */
    printf("%s\n", concat(buf, "hello", "world"));
    return 0;
}

【讨论】:

    【解决方案2】:

    正如之前的评论者所提到的,您需要在某处分配内存来存储连接的字符串。如果不允许您通过 malloc 在堆上分配,那么您可以执行以下操作:

    #include "stdafx.h"
    # include <string.h>
    char* concat( char * result , const char *s1, const char *s2)
    {
        int lengh1 = strlen(s1);
        int lengh2 = strlen(s2);
        int i = 0;
        for (i = 0; i < lengh1; i++) {
            result[i] = s1[i];
        }
        for (i = 0; i < lengh2; i++) {
            result[i+ lengh1] = s2[i];
        }
        return result;
    }
    
    int main()
    {
    
        char mybuffer[100];
        memset(mybuffer, 0, sizeof(mybuffer));
        printf(concat( mybuffer,"hello", "world"));/*output expected "helloworld"*/
        return 0;
    }
    

    【讨论】:

    • 数组可以定义在con concat函数里面吗?
    • 不,你不要那样做。因为内存会在栈空间中分配,函数调用结束后会被释放,进而导致UB。
    • 并非如此。你可以做的是静态的
    • @OldProgrammer 但我们如何在主函数中访问它?
    • concat() 不会写入 空字符。像memset(mybuffer, 0, sizeof(mybuffer)); 那样强制调用代码这样做是这个concat() 的设计弱点。 concat() 缺少大小参数类似于 gets()
    猜你喜欢
    • 1970-01-01
    • 2017-07-01
    • 2014-05-14
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多