我最初使用Microsoft / visual c ++编译器编写了一个作业,但我的课程要求我使用G ++在unix上运行和编译
但是,strncpy_s不能使用g ++进行编译,我的特定程序的任何解决方法都可用吗?
这是使用它的代码段:
void PhoneNumber::setName(const char name[])
{
strncpy_s(_name, name, MAX_NAME_LENGTH);
}
答案 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。