运行代码后,出现以下错误。如何用strcpy_s替换strcpy?谢谢你的帮助。而且,当我尝试直接用strcpy_s替换strcpy时,它说名称空间“ std”没有成员“ strcpy_s”。
严重性代码描述项目文件行抑制状态 错误C4996'strcpy':此函数或变量可能不安全。考虑改用strcpy_s。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。详细信息请参见在线帮助。 Nuitrack_project e:\ nuitracksdk \ nuitrack \ include \ nuitrack \ types \ issue.h 71
严重性代码描述项目文件行抑制状态 错误C4996'strcpy':此函数或变量可能不安全。考虑改用strcpy_s。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。详细信息请参见在线帮助。 Nuitrack_project e:\ nuitracksdk \ nuitrack \ include \ nuitrack \ types \ issue.h 81
#ifndef NUITRACK_ISSUE_H_
#define NUITRACK_ISSUE_H_
#include <memory>
#include <string>
#include<cstring>
namespace tdv
{
namespace nuitrack
{
/**
* @ingroup CommonElements_group
* @brief Describes an issue identifier.
*/
enum IssueId
{
NONE_ISSUE = 0,
FRAME_BORDER_ISSUE = 1,
OCCLUSION_ISSUE = 2,
SENSOR_ISSUE = 3
};
/**
* @ingroup CommonElements_group
* @brief Stores general information about a issue.
*
* Parent class of all issue classes.
*/
class Issue
{
public:
/**
* @brief Smart pointer to access the Issue instance.
*/
typedef std::shared_ptr<Issue> Ptr;
/**
* @brief Returns the issue type as a string.
*/
static std::string getType()
{
static std::string _type = "Issue";
return _type;
}
/**
* @brief Returns the issue name.
*/
virtual std::string getName() const
{
return std::string(_name);
}
/**
* @brief Returns the issue identifier.
*/
IssueId getId()
{
return _id;
}
/**
* @brief Constructs a default issue.
*/
Issue() :
_id(NONE_ISSUE)
{
std::string name = "Issue";
_name = new char[name.length() + 1];
std::strcpy(_name, name.c_str());
}
/**
* @brief Constructs an issue object from its identifier and name.
*/
Issue(IssueId id, const std::string &name) :
_id(id)
{
_name = new char[name.length() + 1];
std::strcpy(_name, name.c_str());
}
virtual ~Issue()
{
deleteString();
}
/**
* Release the memory occupied by the string representation of the name.
*/
void deleteString()
{
if(_name)
{
delete[] _name;
_name = NULL;
}
}
/**
* @brief Copy constructor.
*/
Issue(const Issue& issue)
{
copyIssue(issue);
}
/**
* @brief Overloaded copy assignment operator.
*/
void operator=(const Issue& issue)
{
copyIssue(issue);
}
protected:
/** @warning For internal use only. */
IssueId _id;
/** @warning For internal use only. */
char* _name;
private:
void copyIssue(const Issue& issue)
{
_id = issue._id;
uint32_t nameSize = 0;
while(issue._name[nameSize] != '\0')
nameSize++;
_name = new char[nameSize + 1];
for(uint32_t i = 0; i <= nameSize; i++)
_name[i] = issue._name[i];
}
};
} /* namespace nuitrack */
} /* namespace tdv */
#endif /* NUITRACK_ISSUE_H_ */
答案 0 :(得分:4)
strcpy_s(“ s”代表“安全”)允许您指定目标缓冲区的大小。 std :: strcpy不会执行此操作,因此,如果您的源太长,则会使您超出目标缓冲区的末尾写入,从而产生不良影响。
在上述第一种情况下,请尝试以下操作:
_name = new char[name.length() + 1];
strcpy_s(_name, name.length() + 1, name.c_str());
仅用strcpy_s替换strcpy无效,原因有两个: 1)strcpy_s采用另一个参数(目标缓冲区的长度) 2)strcpy_s不是std的一部分,即std名称空间不包含strcpy_s的声明
因此,请尝试添加额外的参数,并将“ std:strcpy”替换为“ strcpy_s”
如果您使用的是Visual Stdio之类的IDE,则通常可以右键单击诸如“ strcpy_s”之类的术语,然后从出现的上下文菜单中选择诸如“转到声明”之类的内容,并获得有关该术语的一些快速信息。
注意:如果您不熟悉编译和构建C / C ++程序的技巧,也许值得解释该错误消息。该消息告诉您,如果要使用传统的“不安全” c调用(例如strcpy),可以通过在构建系统中的预处理器定义中添加_CRT_SECURE_NO_WARNINGS来实现。在包含相关标头之前,这可以是#define,也可以是IDE中某个位置的条目。如果输入该定义,编译器将允许您使用std :: strcpy而不会抱怨。