为什么这个C语言的字符串联合函数不能使用--segfault?

问题描述 投票:0回答:2

这是一个寻找字符串联合的函数。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>



char* my_union(char* param_1, char* param_2)
{
    char *res[strlen(param_1) + strlen(param_2)];  //allocate long enough string

    //check if the letter is in result res string 
    for(int i = 0 ; i < strlen(param_1);i++){
        if(strchr(*res,param_1[i]) == NULL){// this checks for duplicates
            res[i] = param_1[i];
        }
    }

    for(int i = 0 ; i < strlen(param_2);i++){
        if (strchr(*res, param_2[i])== NULL){//this checks for duplicates too
            *res[i] = param_2[i];
        }
    }

    printf("%s\n", *res);
    return *res;

}


int main(){
    char *s1 = "zpadinton" ;
    char *s2 =  "paqefwtdjetyiytjneytjoeyjnejeyj";
    my_union(s1,s2);// must return "zpadintoqefwjy"
   //the union is zpadintoqefwjy
    return 0;
}
c string union c99
2个回答
0
投票

char *res[strlen(param_1) + strlen(param_2)]; /分配足够长的字符串。

你不能在栈上分配动态长度。你需要在堆上分配它,像这样。

char *res = malloc(strlen(param_1) + strlen(param_2)+1);

(注意:为空结束符多加一个字节)

你需要将缓冲区设置为0,以便以后能够使用strchr。

memset(res, 0, strlen(param_1) + strlen(param_2)+1);

if(strchr(*res,param_1[i]) == NULL){/ 这将检查重复的内容 res[i] = param_1[i]; }。

strchr应该取 res,不 *res.分配给指数 i 将无法工作,因为你需要在结果字符串的末尾添加新字符。

int j=0;
for(int i = 0 ; i < strlen(param_1);i++){
    if(strchr(res,param_1[i]) == NULL){// this checks for duplicates
        res[j] = param_1[i];
        j++;
    }
}

for(i = 0 ; i < strlen(param_2);i++){
    if (strchr(res, param_2[i])== NULL){//this checks for duplicates too
        res[j] = param_2[i];
        j++;
    }
}

printf("%s\n", res);
return res;

3
投票

一些基本的错误。

  • char *res[] 是一个指针数组. 你不希望这样。

  • strlen(param_1) + strlen(param_2) 是不够长,你没有为空结束符分配空间。

  • return *res; 返回一个指向局部变量的指针总是错误的,因为当函数返回时,这个变量就离开了范围。

    你要么让被调用者进行分配并写入传递的参数之一,要么你需要为字符串动态分配内存。

值得注意的是,由于你不正确地使用了一个指针数组,所以诸如 res[i] = param_1[i]; 不应该被编译得很干净,你会收到 "来自不兼容类型的赋值""来自整数的指针而没有转换 "之类的警告。你会收到 "assignment from incompatible type""pointer from integer without a cast "之类的警告。

始终阅读并纠正警告。对于一个初学者来说,一个警告几乎100%肯定是一个错误。把你的警告级别调到最大,甚至更好的是,在第一时间阻止无效代码的编译。例如 gccclangicc: -std=c11 -pedantic-errors -Wall -Wextra -Werror.

© www.soinside.com 2019 - 2024. All rights reserved.