这段代码有什么问题?

时间:2011-09-14 01:35:19

标签: c string concatenation string-concatenation

正如你在下面看到的,我已经创建了一个使用C连接2个字符串的程序,你可能会想象这个代码不起作用,我已经通过使用数组符号而不是指针来自己纠正它,它只是工作正常很好,但是我仍然不确定为什么我的代码几乎不能成为我更正的代码的复制品。

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

void concatena(char *str1, char *str2){
 char *strAux;
 int mover;
 mover = 0;
 strAux = (char *)(malloc(strlen(str1) + strlen(str2)+2));
 *(strAux) = '\0';
 if(str1 == '\0')
    *strAux = '\0';
 else
     while(str1 != '\0'){
         *(strAux+mover++)=*(str1++);
     }
 if(str2 == '\0')
         *strAux = '\0';
 else
     while(str2 != '\0'){
         *(strAux+mover++)=*(str2++);
     }
 strAux='\0';
 str1=strAux;
 printf("%s", str1);
 free(strAux);
 }

我仍然是C初学者(是的,我知道有像string.h这样的库,我出于学术原因问这个)我被告知char指针和数组是同一个东西什么东西让我感到困惑。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

我看到的第一个问题是本节:

if(str2 == '\0')
    *strAux = '\0';

在此代码之前,您已使用strAux中的字符串填充str1 然后,如果str2为空,则突然在strAux的开头放置一个空终止符,从而消除了迄今为止所做的所有工作!

我认为你的意图是:

if(*str2 == '\0')
     *(strAux+mover) = '\0';

在你的str2循环之后再次出现同样的问题,你有代码:

strAux='\0';

同样,这会在strAux的开头放置一个空终止符,在它开始之前有效地结束新创建的字符串。


以下是我重新编写代码的方法:

void concatena(char *str1, char *str2){
    char *strAux;
    int mover = 0;

    strAux = (char *)(malloc(strlen(str1) + strlen(str2)+1));  // Changed to +1, NOT +2
    *(strAux) = '\0';   // Start the string as (empty)

    while(*str1 != '\0'){   // Copy the first string over.
         *(strAux+mover++)=*(str1++);
    }

    while(*str2 != '\0'){   // Copy the second string over.
         *(strAux+mover++)=*(str2++);
    }

    *(strAux+mover)='\0';  // End the new, combined string.

    printf("%s", strAux);  // Show the results.
    free(strAux);
 }

答案 1 :(得分:1)

接受相同的约束,这是我(重新)编写代码的方式。不幸的是,有一个规范缺点:是否应该连接第一个字符串连接?或者应该创建一个新字符串?以下是两种方法:

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

char *concatena (const char *str1, const char *str2)
{
        char    *op, *newStr = (char*)malloc (strlen (str1) + strlen (str2) + 1);
        if (!newStr)
        {
                fprintf (stderr, "concatena: error allocating\n");
                return;
        }

        op = newStr;    // set up output pointer
        while (str1 && *str1)   // copy first string
                *op++ = *str1++;

        while (str2 && *str2)   // concatenate second string
                *op++ = *str2++;

        *op = '\000';           // add conventional NUL termination

        return newStr;
}


void concatenb (char *str1, const char *str2)
{
        char    *op;
        if (!str1)
        {
                fprintf (stderr, "concatenb: NULL string 1\n");
                return;
        }

        op = &str1 [strlen (str1)];     // set output pointer at trailing NUL

        while (str2 && *str2)   // concatenate second string
                *op++ = *str2++;

        *op = '\000';           // add conventional NUL termination
}

答案 2 :(得分:0)

strAux = (char *)(malloc(strlen(str1) + strlen(str2)+2));

2 不是必需的,只需 1 即可终止字符。

*(strAux) = '\0';

这应该仅在所有计算结束时发生。不在连接之间,即

while(*str1 != '\0'){  // This loops copies the first string
    // ^ Notice that you need to dereference to check for the termination character.
     *(strAux+mover++)=*(str1++);
}
while(*str2 != '\0'){  // This loop copies the second string
     *(strAux+mover++)=*(str2++);
}
// Finally adding termination character
*(strAux+mover) = '\0'; // since with mover you are keeping track of locations.

答案 3 :(得分:0)

代码中的错误数量令人沮丧。你应该拿起一本好的C书然后重新开始。

首先,有一个库函数可以用来连接字符串:

const unsigned int len = strlen(str1) + strlen(str2) + 1;
char * dst = malloc(len);
strncat(dst, str1, len);
strncat(dst, str2, len);

现在,如果你坚持手动完成,你必须得到指针和解除引用权:

char * d = dst;
while (*str1 != 0) *dst++ = *str1++;
while (*str2 != 0) *dst++ = *str2++;
*dst = 0;
// d now points to the beginning of the concatenated string

两个循环检查输入字符串中的当前字符是否为非零,如果是,则将它们复制到输出字符串中的当前字符,然后输入和输出指针都前进。 (这都是通过使用postfix ++运算符在一次清洗中完成的。)最后,将最后一个字符设置为零以创建新的空终止符。

在此过程中,我们修改了所有三个指针dststr1str2。后两个作为输入函数参数通过副本进入,所以没关系。为了返回连接字符串,我们在循环之前创建了dst的副本,最后我们可以返回。