C++ 这里的strncpy_()有什么问题?

C++ 这里的strncpy_()有什么问题?,c++,strncpy,C++,Strncpy,我正在读我的书,试图解决给读者的问题 休闲代码是我的答案源文件中的函数定义 我想将字符串的内容复制到另一个字符串 我选择了函数strncpy\s() 但它不起作用 Microsoft Visual Studio表示调试断言失败 我不知道如何修理它 母牛 //类声明 #include <iostream> #ifndef COW_H_ #define COW_H_ class Cow { char name[20]; char * hobby; double weight; publ

我正在读我的书,试图解决给读者的问题

休闲代码是我的答案源文件中的函数定义

我想将字符串的内容复制到另一个字符串

我选择了函数strncpy\s()

但它不起作用

Microsoft Visual Studio表示调试断言失败

我不知道如何修理它

母牛

//类声明

#include <iostream>
#ifndef COW_H_
#define COW_H_

class Cow {
char name[20];
char * hobby;
double weight;
public:
Cow();
Cow(const char * nm, const char * ho, double wt);
Cow(const Cow & c);
~Cow();
Cow & operator=(const Cow & c);
void ShowCow() const;  // display all cow data   
}; 
#endif
#包括
#伊芬德夫牛_
#定义COW_H_
阶级母牛{
字符名[20];
爱好;
双倍重量;
公众:
奶牛();
Cow(常量字符*纳米,常量字符*纳米,双重量);
奶牛(const-Cow&c);
~Cow();
Cow和操作员=(常数Cow和c);
void ShowCow()const;//显示所有cow数据
}; 
#恩迪夫
cow.cpp

//类方法

Cow::Cow(const char * nm, const char * ho, double wt)
{
    int len = std::strlen(nm);
    strncpy_s(name, len, nm, len);
    name[19] = '\0';

    len = std::strlen(ho);
    hobby = new char[len + 1];
    strncpy_s(hobby, len, ho, len);
    hobby[len] = '\0';

    weight = wt;
}

Cow::Cow()
{
    strncpy_s(name, 19, "no name", 19);
    name[19] = '\0';

    int len = std::strlen("no hobby");
    hobby = new char[len + 1];
    strncpy_s(hobby, len, "no hobby", len);
    hobby[len] = '\0';

    weight = 0.0;
}

Cow::Cow(const Cow & c)
{
    int len = std::strlen(c.name);
    strncpy_s(name, len, c.name, len);
    name[19] = '\0';

    len = std::strlen(c.hobby);
    hobby = new char[len + 1];
    strncpy_s(hobby, len, c.hobby, len);
    hobby[len] = '\0';

    weight = c.weight;
}

Cow::~Cow()
{
    delete [] hobby;
}

Cow & Cow::operator=(const Cow & c)
{
    if (this == &c)
        return * this;

    delete [] hobby;

    int len = std::strlen(c.name);
    strncpy_s(name, len, c.name, len);
    name[19] = '\0';

    len = std::strlen(c.hobby);
    hobby = new char[len + 1];
    strncpy_s(hobby, len, c.hobby, len);
    hobby[len] = '\0';

    weight = c.weight;
    return * this;
}

void Cow::ShowCow() const
{
    cout << name << ", " << hobby << ", " << weight << endl;  
}
Cow::Cow(常量字符*nm,常量字符*ho,双wt)
{
int len=std::strlen(纳米);
strncpy_s(名称、长度、nm、长度);
名称[19]=“0”;
len=std::strlen(ho);
爱好=新字符[len+1];
strncpy_s(爱好、爱好、爱好、爱好、爱好);
爱好[len]='\0';
重量=重量;
}
牛::牛()
{
strncpy_s(姓名,19,“无姓名”,19);
名称[19]=“0”;
int len=std::strlen(“无爱好”);
爱好=新字符[len+1];
strncpy____s(嗜好,len,“无嗜好”,len);
爱好[len]='\0';
重量=0.0;
}
奶牛:奶牛(const-Cow&c)
{
int len=std::strlen(c.name);
strncpy_s(姓名,len,c.name,len);
名称[19]=“0”;
len=std::strlen(c.hobby);
爱好=新字符[len+1];
strncpy_ès(hobby,len,c.hobby,len);
爱好[len]='\0';
重量=c.重量;
}
牛::~Cow()
{
删除[]爱好;
}
Cow和Cow::运算符=(常量Cow和c)
{
如果(此==&c)
归还*这个;
删除[]爱好;
int len=std::strlen(c.name);
strncpy_s(姓名,len,c.name,len);
名称[19]=“0”;
len=std::strlen(c.hobby);
爱好=新字符[len+1];
strncpy_ès(hobby,len,c.hobby,len);
爱好[len]='\0';
重量=c.重量;
归还*这个;
}
void Cow::ShowCow()常量
{

从标准代码到标准代码:

这些函数尝试将strSource的前D个字符复制到 strDest,其中D是count和strSource的长度中的较小者。 如果这些D字符适合strDest(其大小如下所示 numberOfElements)并仍然为空终止符留出空间 复制这些字符并附加终止null; 否则,strDest[0]被设置为空字符,并且无效 调用参数处理程序,如参数验证中所述

让我们考虑你的代码:

int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len, "no hobby", len);
strcpy\u s
的第二个参数是缓冲区的大小(以字符为单位)。第四个参数是复制的字符数。由于您传递的是相同的
len
变量,
strcpy\u s
检测到缓冲区大小不足(因为应该有一个用于尾随\0的空间)并调用无效的参数处理程序。此操作正常:

int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len+1, "no hobby", len);
检查您正在使用
strncpy\s
的其他地方是否存在此错误。 另外,在调试断言窗口中实际读取文本也是一个好主意。在这种情况下,错误源非常简单:


来自《代码》杂志

这些函数尝试将strSource的前D个字符复制到 strDest,其中D是count和strSource的长度中的较小者。 如果这些D字符适合strDest(其大小如下所示 numberOfElements)并仍然为空终止符留出空间 复制这些字符并附加终止null; 否则,strDest[0]被设置为空字符,并且无效 调用参数处理程序,如参数验证中所述

让我们考虑你的代码:

int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len, "no hobby", len);
strcpy\u s
的第二个参数是缓冲区的大小(以字符为单位)。第四个参数是复制的字符数。由于您传递的是相同的
len
变量,
strcpy\u s
检测到缓冲区大小不足(因为应该有一个用于尾随\0的空间)并调用无效的参数处理程序。此操作正常:

int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len+1, "no hobby", len);
检查您正在使用
strncpy\s
的其他地方是否存在此错误。 另外,在调试断言窗口中实际读取文本也是一个好主意。在这种情况下,错误源非常简单:

首先,第二行应该使用
len+1
而不是
len
。其次,它应该使用
strcpy
而不是
strncpy

计算源(
strlen(nm)
)的长度不会提供任何有关目标缓冲区大小的信息(
name
)。而且,由于没有关于目标缓冲区大小的信息,因此限制要复制的字符数是没有意义的。因此,不要做所有旋转。只需复制字符串:

strcpy(name, nm);
首先,第二行应该使用
len+1
而不是
len
。其次,它应该使用
strcpy
而不是
strncpy

计算源(
strlen(nm)
)的长度不会提供任何有关目标缓冲区大小的信息(
name
)。而且,由于没有关于目标缓冲区大小的信息,因此限制要复制的字符数是没有意义的。因此,不要做所有旋转。只需复制字符串:

strcpy(name, nm);

请在使用
Cow
类的地方添加代码。您是否按照手册所述检查了传递的参数?在一个地方,您只传递
3
参数,但在另一个地方,您将
4
参数传递到
strncpy\u s
@Ari0nhh是的,我刚才添加了usecow.cpp。@Galik我想strncpy\u s()在这些方面是一个重载函数。请在使用
Cow
类的地方添加代码。您是否按照手册所述检查了所传递的参数?在一个地方您只传递
3
参数,但在另一个地方传递
4