strncpy_s使用G ++编译器

0 c++ g++ strncpy

我最初使用Microsoft/visual c ++编译器编写了一个作业,但我的课程要求我使用G ++在unix上运行和编译

但是,strncpy_s不能使用g ++编译,我的特定程序的任何解决方法?

这是使用它的代码段:

void PhoneNumber::setName(const char name[])
{
    strncpy_s(_name, name, MAX_NAME_LENGTH);
}
Run Code Online (Sandbox Code Playgroud)

rub*_*nvb 7

这些*_s功能是微软试图聪明地"保护"C运行时库的字符串函数.这些函数甚至已经成为C99的附录K.在撰写本文时,它们并没有在Linux的glibc中实现.如果你绝对必须(我建议反对它),只需正确使用正常的C库函数(这意味着没有神奇的数字和适当的缓冲区大小),是的,这是一个痛苦的屁股.

这可能会或可能不会在您的任务中使用,但它确实是唯一正确的答案:

class PhoneNumber
{
private:
  std::string name;
  // ...
public:
  void setName(std::string name);
  //...
};

void PhoneNumber::setName(std::string name)
{
  this->name = std::move(name); // 'this->' is optional, but clarifies without resorting to some clever renaming of the variables
}
Run Code Online (Sandbox Code Playgroud)

或者,完全放弃setter:

struct PhoneNumber
{
  std::string name;
  // ...
};
Run Code Online (Sandbox Code Playgroud)

并直接分配会员.但是这种编码风格虽然完全合理,但可能会让你的老师大吼大叫.

不要在C++中使用C char数组.你没有任何理由在脚下开枪.它还消除了代码中的幻数,这总是一个加号.


Tiny C++ 11及更高版本模板wankery.实现setter的理想解决方案是使用模板,因此如果调用setter,可以防止潜在的昂贵的双重移动setName(std::move(some_string)):

template<typename T>
void setName(T&& name) { this->name = std::forward<T>(name); }
Run Code Online (Sandbox Code Playgroud)

这将允许接受任何可分配/可移动到std :: string的东西,这实际上是相当不错的.作为额外的好处,您可以自动为您选择最佳的代码路径.当然,对于你的任务,这将是一个巨大的矫枉过正,但如果你花时间去了解这些概念,你可能只是教给老师一些东西.再一次,更喜欢public这个模板的成员... wankery,因为这就是它.

  • 最好使用引用来避免方法调用时的对象复制操作+使用const (2认同)