char concat c ++ no library functions

时间:2018-03-09 20:02:17

标签: c++ char

如何连接两个char *但没有库函数,我希望更好地了解这个函数的工作原理。
S1 =“AA”
S2 =“BB”

该函数应返回指向“AABB”;

的指针

这是我已有的代码。

char *  concatenate(char * s1, char * s2)  
{  
    char * p = new char(string_length(s1) + string_length(s2) + 2);  
    return p ;  
}
int string_length(char * s)
{
    unsigned int i = 0;
    while (*s++ != '\0')
        ++i;

    return i;
}

提前致谢

2 个答案:

答案 0 :(得分:2)

这是一种方法:

  1. 创建一个大小为s1 + s2的char *
  2. 遍历第一个字符串和每个字符。
  3. 同样使用第二个字符串的字符填充char *的其余部分。
  4. 添加\0以表示字符串终止。
  5. 另见本帖的所有评论!

    size_t string_length(const char * s)
    {
        size_t i = 0;
        while (*s++ != '\0')
            ++i;
    
        return i;
    }
    
    char *  concatenate(const char * s1, const char * s2)
    {
        size_t l1 = string_length(s1);
        size_t l2 = string_length(s2);
    
        /// Step 1:
        char * p = new char[l1 + l2 + 1];
    
        /// Step 2:
        for (size_t i = 0; i < l1; i++) {
            p[i] = s1[i];
        }
        /// Step 3:
        for (size_t i = 0; i < l2; i++) {
            p[i + l1] = s2[i];
        }
    
        /// Step 4:
        p[l1 + l2] = '\0';
    
        return p;
    }
    
    
    int main()
    {
    
        char* test = concatenate("first", "second");
        cout << test;
    
        /// Delete after use.
        delete[] test;
        cin.get();
        return 0;
    }
    

答案 1 :(得分:1)

要连接两个char字符串,需要做出一些设计决策。

最关键的是你是否希望串联功能的用户提供他们自己的存储区来保存字符串,或者你想自己提供足够大的区域。

让用户提供区域的好处是用户可以选择连接字符串的去向,用户可以决定如何管理内存。

因此,我们创建几个相关的功能,提供此功能,并允许用户决定他们需要多少或几乎没有帮助。

template <typename T>
size_t Str_len(const T *s1)
{

    const T *const sStart = s1;
    if (s1)  while (*s1) s1++;    // guard against nullptr
    return s1 - sStart;
}

template <typename T>
T *Str_alloc(size_t nChars)
{
    T * p = new T[nChars + 1];    // plus 1 for end of string character

    p && nChars > 0 && (*p = 0);  // initialize new string with end of string if possible
    return p;
}

template <typename T>
void Str_delete(T *src)
{
    delete [] src;    // new array requires delete array
}

template <typename T>
T *Str_cpy(T *dest, const T *src)
{
    T * const destStart = dest;  // will return beginning of dest
    if (src && dest) {
        while (*dest++ = *src++);    // copy from src to dest including end of string
    }
    return destStart;
}

template <typename T>
T *Str_cat(T *dest, const T *src)
{
    if (src && dest) {
        T * const destStart = dest;  // will return beginning of dest
        while (*dest) dest++;     // find end of string of dest
        Str_cpy(dest, src);       // copy src to end of dest
        return destStart ;
    }
    else {
        return dest;  // bad args so just return dest
    }
}

template <typename T>
T *Str_cat_alloc(const T *s1, const T *s2)
{
    size_t nChars = Str_len(s1) + Str_len(s2);
    auto dest = Str_alloc <T> (nChars);
    if (dest && s1) {
        Str_cpy(dest, s1);
        if (s2) {
            Str_cat(dest, s2);
        }
        return dest;
    }
    else {
        return dest;
    }
}

这些将用于:

int main(int argc, char * argv[])
{

    auto p1 = Str_alloc <char> (28);
    auto p2 = Str_alloc <char>(32);

    Str_cpy(p1, "this test");
    Str_cpy (p2, p1);
    Str_cat (p2, "xxx");

    auto p3 = Str_alloc <char> (Str_len(p1) + Str_len(p2));
    Str_cat (p3, p1);
    auto p4 = Str_cat (p3, p2);

    auto p5 = Str_cat_alloc("this is one ", "this is two");
    Str_delete (p1);
    Str_delete (p2);
    Str_delete(p3);
    // no delete on p4 as it is a copy of p3
    // see how confusing C style memory management can be?
    Str_delete(p5);

    return 0;
}

附录:使用可变参数模板

这是使用可变参数模板的另一个例子,它以令人愉快的方式允许可变数量的参数。此示例已使用Visual Studio 2017 Community Edition进行编译和测试。

template <typename T>
T *Str_cat(T *a, const T * b)
{
    T *pSave = a;
    while (*a) a++;
    while (*a++ = *b++);
    return pSave;
}

template <typename T, typename... Args>
T *Str_cat(T *a, const T *b, Args... args)
{
    T *pSave = a;
    while (*a) a++;
    for (; *a = *b; a++, b++);
    Str_cat(a, args...);

    return pSave;
}

template <typename T>
size_t Str_len(T *a)
{
    T *pSave = a;
    while (*a) a++;
    return a - pSave;
}

template <typename T, typename... Args>
size_t Str_len(T *a, Args... args)
{
    return Str_len(a) + Str_len(args...);
}

这些功能可以如下使用。

int main (int argc, char *argv)
{
    char p[]  = "this is p1";
    char p2[] = "this is p2";
    char p3[] = "this is p3";
    char p4[] = "this is p4";
    char p5[] = "this is p5";
    char bigbuff[512];

    auto i = Str_len(p, p2, p3, p4);

    bigbuff[0] = 0;
    Str_cat(bigbuff, p, p2, p3);
    bigbuff[0] = 0;
    Str_cat(bigbuff, p, p2, p3, p4, p5);

    return 0;
}