strncpy_s() 这里有什么问题?
What is wrong with strncpy_s() here?
我正在阅读我的教科书并尝试解决给读者的问题。
下面的代码是我的答案源文件中的函数定义。
我想将字符串的内容复制到另一个字符串中。
我选择了函数strncpy_s()。
但是不行。
Microsoft Visual Studio 说调试断言失败!
我不知道如何解决它。
cow.h
// class 声明
#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.cpp
// class 方法
Cow::Cow(const char * nm, const char * ho, double wt)
{
int len = std::strlen(nm);
strncpy_s(name, len, nm, len);
name[19] = '[=12=]';
len = std::strlen(ho);
hobby = new char[len + 1];
strncpy_s(hobby, len, ho, len);
hobby[len] = '[=12=]';
weight = wt;
}
Cow::Cow()
{
strncpy_s(name, 19, "no name", 19);
name[19] = '[=12=]';
int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len, "no hobby", len);
hobby[len] = '[=12=]';
weight = 0.0;
}
Cow::Cow(const Cow & c)
{
int len = std::strlen(c.name);
strncpy_s(name, len, c.name, len);
name[19] = '[=12=]';
len = std::strlen(c.hobby);
hobby = new char[len + 1];
strncpy_s(hobby, len, c.hobby, len);
hobby[len] = '[=12=]';
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] = '[=12=]';
len = std::strlen(c.hobby);
hobby = new char[len + 1];
strncpy_s(hobby, len, c.hobby, len);
hobby[len] = '[=12=]';
weight = c.weight;
return * this;
}
void Cow::ShowCow() const
{
cout << name << ", " << hobby << ", " << weight << endl;
}
usecow.cpp
#include <iostream>
#include "cow.h"
int main()
{
Cow Japan;
Japan.ShowCow();
Cow America("Aspen", "Swim", 307.45);
America.ShowCow();
return 0;
}
来自 strncpy_s
documentation:
These functions try to copy the first D characters of strSource to
strDest, where D is the lesser of count and the length of strSource.
If those D characters will fit within strDest (whose size is given as
numberOfElements) and still leave room for a null terminator, then
those characters are copied and a terminating null is appended;
otherwise, strDest[0] is set to the null character and the invalid
parameter handler is invoked, as described in Parameter Validation.
让我们考虑一下您的代码:
int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len, "no hobby", len);
strcpy_s
的第二个参数是以字符为单位的缓冲区大小。第四 - 复制的字符数。由于您正在传递相同的 len
变量,strcpy_s
检测到该缓冲区的大小不足(因为尾随 \0 应该有一个 space)并调用无效参数处理程序。这可以正常工作:
int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len+1, "no hobby", len);
检查您使用 strncpy_s
的其他地方是否存在此错误。
实际读取调试断言 windows 中的文本也是一个好主意。在这种情况下,错误来源非常简单:
int len = std::strlen(nm);
strncpy_s(name, len, nm, len);
首先,第二行应该使用len + 1
而不是len
。其次,它应该使用 strcpy
而不是 strncpy_s
.
计算源的长度 (strlen(nm)
) 不提供有关目标缓冲区 (name
) 大小的任何信息。并且由于没有关于目标缓冲区大小的信息,限制要复制的字符数是没有意义的。所以不要做所有那些旋转的事情。只需复制字符串:
strcpy(name, nm);
我正在阅读我的教科书并尝试解决给读者的问题。
下面的代码是我的答案源文件中的函数定义。
我想将字符串的内容复制到另一个字符串中。
我选择了函数strncpy_s()。
但是不行。
Microsoft Visual Studio 说调试断言失败!
我不知道如何解决它。
cow.h
// class 声明
#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.cpp
// class 方法
Cow::Cow(const char * nm, const char * ho, double wt)
{
int len = std::strlen(nm);
strncpy_s(name, len, nm, len);
name[19] = '[=12=]';
len = std::strlen(ho);
hobby = new char[len + 1];
strncpy_s(hobby, len, ho, len);
hobby[len] = '[=12=]';
weight = wt;
}
Cow::Cow()
{
strncpy_s(name, 19, "no name", 19);
name[19] = '[=12=]';
int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len, "no hobby", len);
hobby[len] = '[=12=]';
weight = 0.0;
}
Cow::Cow(const Cow & c)
{
int len = std::strlen(c.name);
strncpy_s(name, len, c.name, len);
name[19] = '[=12=]';
len = std::strlen(c.hobby);
hobby = new char[len + 1];
strncpy_s(hobby, len, c.hobby, len);
hobby[len] = '[=12=]';
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] = '[=12=]';
len = std::strlen(c.hobby);
hobby = new char[len + 1];
strncpy_s(hobby, len, c.hobby, len);
hobby[len] = '[=12=]';
weight = c.weight;
return * this;
}
void Cow::ShowCow() const
{
cout << name << ", " << hobby << ", " << weight << endl;
}
usecow.cpp
#include <iostream>
#include "cow.h"
int main()
{
Cow Japan;
Japan.ShowCow();
Cow America("Aspen", "Swim", 307.45);
America.ShowCow();
return 0;
}
来自 strncpy_s
documentation:
These functions try to copy the first D characters of strSource to strDest, where D is the lesser of count and the length of strSource. If those D characters will fit within strDest (whose size is given as numberOfElements) and still leave room for a null terminator, then those characters are copied and a terminating null is appended; otherwise, strDest[0] is set to the null character and the invalid parameter handler is invoked, as described in Parameter Validation.
让我们考虑一下您的代码:
int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len, "no hobby", len);
strcpy_s
的第二个参数是以字符为单位的缓冲区大小。第四 - 复制的字符数。由于您正在传递相同的 len
变量,strcpy_s
检测到该缓冲区的大小不足(因为尾随 \0 应该有一个 space)并调用无效参数处理程序。这可以正常工作:
int len = std::strlen("no hobby");
hobby = new char[len + 1];
strncpy_s(hobby, len+1, "no hobby", len);
检查您使用 strncpy_s
的其他地方是否存在此错误。
实际读取调试断言 windows 中的文本也是一个好主意。在这种情况下,错误来源非常简单:
int len = std::strlen(nm);
strncpy_s(name, len, nm, len);
首先,第二行应该使用len + 1
而不是len
。其次,它应该使用 strcpy
而不是 strncpy_s
.
计算源的长度 (strlen(nm)
) 不提供有关目标缓冲区 (name
) 大小的任何信息。并且由于没有关于目标缓冲区大小的信息,限制要复制的字符数是没有意义的。所以不要做所有那些旋转的事情。只需复制字符串:
strcpy(name, nm);