如何复制strncat(原创)

时间:2017-10-26 18:40:06

标签: c++ string pointers c-strings

我的stringNAdd函数将复制strncat(原始)。我不能接受数组作为参数,而是指针。我想知道我的代码是否合适?

这是固定代码:

#include <string>
#include <iostream>

using namespace std;

char *stringNAdd(char str1[], char str2[],size_t num);
int main()
{
    char dest[50] = "Using strncat function,";
    char src[50] = " this part is added and this is ignored";
    cout<< strncat(dest, src, 20) << endl;
    cout << stringNAdd(dest, src, 20) << endl;
    cin.get();
    return 0;

}

char *stringNAdd(char str1[], char str2[],size_t num){
    size_t str1_len = strlen(str1);
    size_t i;

    for (i=0; i < num && str2[i] != '\0'; i++)
        i==num;
     str1[str1_len+i] = str2[i];
     str1[str1_len+i] = '\0';

    return str1;
}
  

输出:

     

使用strncat函数,添加此部分

     

使用strncat函数,添加此部分

2 个答案:

答案 0 :(得分:2)

问题是您不能在相同条件下对这两项功能进行测试:一旦您执行了strncat()dest已经包含了更长的连接版本。

第二个问题是dest已经扩大了15个字符。因此,在调用stringNAdd()之前,它的初始长度为38个字符+空终止符。再添加15个字符会产生一个包含53个字符的字符串加上一个空终止符,这比您的数组长4个字符。因此,您将获得缓冲区溢出,从而导致内存损坏和未定义的行为。

但所有这些都与测试条件有关:你的克隆工作正常。

建议:

在不同的块中运行您的函数,并定义该块的本地测试变量:

{
char dest[50] = "Using strncat function,";
char src[50] = " this part is added and this is ignored";
cout<< strncat(dest, src, 15) << endl;
cout << strlen(dest)<<endl;
}
{
char dest[50] = "Using strncat function,";
char src[50] = " this part is added and this is ignored";
cout << stringNAdd(dest, src, 15) << endl;
}

考虑一个更安全的函数版本,在该版本中,您将在目标数组的总长度上有一个额外的参数来防止这些错误。这样可以提高代码的安全性。顺便说一下,这就是微软对strncat_s()所做的事情。

最后,你可以问你的老师,为什么他/她仍然可以让你使用cstrings,当有更方便和安全的std::string,并且他当然可以找到更多现代化的练习与相同的教学法好处。

答案 1 :(得分:1)

以下是基于https://opensource.apple.com/source/Libc/Libc-167/gen.subproj/i386.subproj/strncat.c

的等效内容
#include <iostream>

char *strnadd(char *dst, const char *src, size_t n)
{
    // abort if source is empty
    if (n != 0) 
    {
        // copy pointers
        char *d = dst;
        const char *s = src;

        // find end of destination str
        while (*d != 0)
            d++;

        // start copying chars from source str to the end of destination str
        // until either source string ends or number of chars copied 
        // destination string has to be long enough to accommodate source
        do 
        {
            if ((*d = *s++) == 0)
                break;
            d++;
        } 
        while (--n != 0);

        // add null termination
        *d = 0;
    }

    // return the resulting string
    return dst;
}

int main()
{
    char strCat[50];
    char strAdd[50];

    strcpy(strCat, "string1");
    strcpy(strAdd, "string1");

    char const *str2 = "string2";

    std::cout << strncat(strCat, str2, 6) << std::endl;
    std::cout << strnadd(strAdd, str2, 6) << std::endl;

    return 0;
}

打印:

string1string
string1string