C 字符串的分配,一个字符串中两个字符串的递归函数

C 字符串的分配,一个字符串中两个字符串的递归函数,c,string,recursion,C,String,Recursion,我编写了一个递归函数,得到3个字符串,其中两个按字母顺序排序,第三个按字母顺序分配,将前两个字符串放入第三个字符串中。字母顺序应该保持不变;例如: s1="abbcde"; s2="bckj"; 所以 这是main()中第三个字符串的分配: 这就是功能: void SS1together(char *s1, char*s2, char*s3) { if (s1 == NULL || s2 == NULL) { if (s1 == NULL) { s3[0]

我编写了一个递归函数,得到3个字符串,其中两个按字母顺序排序,第三个按字母顺序分配,将前两个字符串放入第三个字符串中。字母顺序应该保持不变;例如:

s1="abbcde";
s2="bckj";
所以

这是
main()
中第三个字符串的分配:

这就是功能:

   void SS1together(char *s1, char*s2, char*s3)
{
if (s1 == NULL || s2 == NULL)
{
    if (s1 == NULL)
    {
        s3[0] = s2[0];
        SS1together(s1, s2 + 1, s3 + 1);

    }
    else
    {
        s3[0] = s1[0];
        SS1together(s1 + 1, s2, s3 + 1);
    }
}
if (s1 != NULL && s2 != NULL)
{
    if (s1[0] <= s2[0])
    {
        s3[0] = s1[0];
        SS1together(s1 + 1, s2, s3 + 1);
    }
    else
    {
        s3[0] = s2[0];
        SS1together(s1 , s2 + 1, s3 + 1);
    }
}
}

您的代码假设当
s1
NULL
(第一个
if
)时,
s2
不是
NULL
并递增
s2
,并执行递归调用

但是当
s2
字符串小于
s1
时,
s2
将首先到达末尾,因此在递归调用中传递
s2+1
将导致访问超限内存。这在技术上会导致未定义的行为,实际上最有可能导致崩溃的内存访问冲突


在递增指针之前,您应该进行更严格的空检查-
s1
s2
s3

,您处于中等接近状态,但尚未充分考虑终止条件。它也是一个整体堆,迭代合并排序数据比递归合并更容易

您不会显示len是如何计算的(它需要是
strlen(s1)+strlen(s2)+1
),但即使这是正确的,您的代码也可能会遇到问题。例如,考虑最简单的情况,两个空字符串。第一个
if
执行,但递归将使用
s2+1
,这超出了字符串的末尾,并导致灾难。我认为,修复这一问题需要类似以下代码:

void SS1together(char *s1, char *s2, char *s3)
{
    if (s1 == NULL || s1[0] == '\0')
    {
        s3[0] = s2[0];
        if (s2[0] != '\0')
            SS1together(s1, s2 + 1, s3 + 1);
    }
    else if (s2 == NULL|| s2[0]=='\0')
    {
        s3[0] = s1[0];
        if (s1[0] != '\0')
            SS1together(s1 + 1, s2, s3 + 1);
    }
    else if (s1[0] <= s2[0])
    {
        s3[0] = s1[0];
        SS1together(s1 + 1, s2, s3 + 1);
    }
    else
    {
        s3[0] = s2[0];
        SS1together(s1, s2 + 1, s3 + 1);
    }
}
void ss1一起(char*s1、char*s2、char*s3)
{
如果(s1==NULL | | s1[0]='\0')
{
s3[0]=s2[0];
如果(s2[0]!='\0')
SS1(s1、s2+1、s3+1);
}
else如果(s2==NULL | | s2[0]='\0')
{
s3[0]=s1[0];
如果(s1[0]!='\0')
SS1(s1+1、s2、s3+1);
}

else if(s1[0]我将其固定为:if(s1==NULL | | | s1[0]='\0'| | | s2==NULL | | s2[0]='\0')这是第一个if,然后在另外两个if中,一个为s1==NULL,另一个为s2==NULL,但仍然存在问题/@t| box24:更新您的问题,而不使此答案无效(因此添加修改后的代码,而不是替换原来的代码)。您可以控制问题中的格式;您不能有意义地格式化注释。@t_box24,测试也应该针对
*s1==NULL
*s2==NULL
。您不显示如何计算
len
(它需要是
strlen(s1)+strlen(s2)+1
),也不显示输出字符串是如何以NULL结尾的(虽然它可能会自动发生-在声称它不会发生之前,我有一些事情要做;但是我担心第一个
if
子句if
s2[0]='\0'
中的递归同时
s1[0]='\0'
)。看起来你只是在尝试,这可能比你最初想象的要简单)。而您发布的代码在分配
s3
时缺少一个
+1
,以说明随后的终止符。这种行:“s3[0]=s2[0];”不复制字符串,它只复制字符串的第一个字节。实际需要的是:“strcpy(s3,s2);”而s3需要是s3=malloc(strlen(s1)+strlen(s2)+1);注意:sizeof(char)始终是1I忘记len=strlen(s1)+strlen(s2)+1
   void SS1together(char *s1, char*s2, char*s3)
{
if (s1 == NULL || s2 == NULL)
{
    if (s1 == NULL)
    {
        s3[0] = s2[0];
        SS1together(s1, s2 + 1, s3 + 1);

    }
    else
    {
        s3[0] = s1[0];
        SS1together(s1 + 1, s2, s3 + 1);
    }
}
if (s1 != NULL && s2 != NULL)
{
    if (s1[0] <= s2[0])
    {
        s3[0] = s1[0];
        SS1together(s1 + 1, s2, s3 + 1);
    }
    else
    {
        s3[0] = s2[0];
        SS1together(s1 , s2 + 1, s3 + 1);
    }
}
}
  void main()
{
char *s1[N], *s2[N], *s3[N];//N=30 ,it is define in the top
int ans, len;

printf("Please enter your string  s1 and then string s2\n");
gets(s1);
gets(s2);
len = strlen(s1) + strlen(s2);

if ((CheckS(s1) == 0) || (CheckS(s2) == 0))
    printf("Not sorted\n");
else
{
    char *s3 = (char*)malloc(len*sizeof(char));
    SS1together(s1,s2,s3);
    puts(s3);
    free(s3);
}
_getch();
}
void SS1together(char *s1, char *s2, char *s3)
{
    if (s1 == NULL || s1[0] == '\0')
    {
        s3[0] = s2[0];
        if (s2[0] != '\0')
            SS1together(s1, s2 + 1, s3 + 1);
    }
    else if (s2 == NULL|| s2[0]=='\0')
    {
        s3[0] = s1[0];
        if (s1[0] != '\0')
            SS1together(s1 + 1, s2, s3 + 1);
    }
    else if (s1[0] <= s2[0])
    {
        s3[0] = s1[0];
        SS1together(s1 + 1, s2, s3 + 1);
    }
    else
    {
        s3[0] = s2[0];
        SS1together(s1, s2 + 1, s3 + 1);
    }
}
void SS1together(char *s1, char *s2, char *s3)
{
    if (s1 == NULL)
        s1 = "";
    if (s2 == NULL)
        s2 = "";
    while (*s1 != '\0' && *s2 != '\0')
    {
        if (s1[0] <= s2[0])
            *s3++ = *s1++;
        else
            *s3++ = *s2++;
    }
    while (s1[0] != '\0')
        *s3++ = *s1++;
    while (s2[0] != '\0')
        *s3++ = *s2++;
    *s3 = '\0';
}