strncpy_s使用G ++编译器

时间:2015-02-06 15:10:02

标签: c++ g++ strncpy

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

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

这是使用它的代码段:

void PhoneNumber::setName(const char name[])
{
    strncpy_s(_name, name, MAX_NAME_LENGTH);
}

2 个答案:

答案 0 :(得分: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
}

或者,完全放弃二传手:

struct PhoneNumber
{
  std::string name;
  // ...
};

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

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


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

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

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

答案 1 :(得分:-1)

您不应该使用strncpy或其_s版本it may be quite surprising in its behaviour

请改为使用strlcpy,请参阅strlcpy and strlcat - consistent, safe, string copy and concatenation