strncpy引入了有趣的角色

时间:2012-02-27 12:08:52

标签: c strncpy

当我在我的机器上运行一些代码时,它的行为就像我期望的那样。

当我在同事身上跑它时,它行为不端。这就是发生的事情。

我有一个值为的字符串:

  

croc_data_0001.idx

当我在提供18的字符串上执行strncpy时,我复制的字符串的值为:

  

croc_data_0001.idx♂

如果我执行以下操作

myCopiedString[18]='\0';
puts (myCopiedString);

然后复制的字符串的值为:

  

croc_data_0001.idx

可能导致此问题的原因是什么,通过将最后一个字符设置为\0来解决问题?

5 个答案:

答案 0 :(得分:5)

根据http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

char * strncpy ( char * destination, const char * source, size_t num );
Copy characters from string
  

将源的前几个num字符复制到目标。如果结束   源C字符串(由空字符表示)是   在复制num个字符之前找到,目的地被填充   用零写入,直到写入总数为num个字符。        没有空字符隐式附加到目标的末尾,因此如果长度,目标将仅以空值终止   源中的C字符串小于num。

因此,您需要使用'\ 0'手动终止目的地。

答案 1 :(得分:1)

strncpy不希望复制字符串的大小,而是希望复制目标缓冲区的大小。

在您的情况下,目标缓冲区太短,禁用strncpy以零终止字符串。所以字符串背后的所有内容都是如此。位置18和非零将被视为属于字符串。

通常情况下,调用缓冲区大小的函数就是这样,i。即

char dest[50];
strncpy(dest, "croc_data_0001.idx", sizeof dest);

有了这个和一个额外的

dest[sizeof dest - 1] = '\0';

字符串将始终以0结尾。

答案 2 :(得分:1)

我认为C标准比其他人发布的链接更清晰地描述了这个功能。

ISO 9899:2011

  

7.24.2.4 strncpy函数

char *strncpy (char * restrict s1,
               const char * restrict s2,
               size_t n);
  

strncpy函数复制不超过n个字符(跟随null的字符)   字符未被复制)从s2指向的数组到s1指向的数组。如果在重叠的对象之间进行复制,则行为未定义。

     

如果s2指向的数组是一个短于n个字符的字符串,则为空字符   被附加到s1指向的数组中的副本,直到所有的字符都是   写入。

答案 3 :(得分:0)

strncpy并不总是添加\0.请参阅http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

因此,请事先清除目标缓冲区,或者始终自行添加\0,或使用strcpy

如果问题是:“为什么我的机器上的未初始化内存与另一台机器上的内容不同”,那么,人们只能猜测。

编辑稍微改变了措辞;见评论。

答案 4 :(得分:0)

myCopiedString变量分配了多少空间?如果它超过源字符串的长度,那么请确保使用bzero清除目标变量。