如何用strcpy_s替换strcpy?

时间:2019-01-05 23:34:39

标签: c++

运行代码后,出现以下错误。如何用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_ */

1 个答案:

答案 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而不会抱怨。