2

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

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

我有一个值为:

croc_data_0001.idx

当我strncpy对提供 18 作为长度的字符串执行 a 时,我复制的字符串的值为:

croc_data_0001.idx♂</p>

如果我执行以下操作

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

那么复制的字符串的值为:

croc_data_0001.idx

什么可能导致这个问题,为什么通过将最后一个字符设置为来解决它\0

4

5 回答 5

5

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

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

将源的前 num 个字符复制到目标。如果在复制 num 个字符之前找到源 C 字符串的结尾(由空字符表示),则用零填充目标,直到总共写入了 num 个字符。没有空字符隐式附加到目标的末尾,因此只有当源中 C 字符串的长度小于 num 时,目标才会以空字符结尾。

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

于 2012-02-27T12:14:21.800 回答
1

我认为 C 标准以比其他人发布的链接更清晰的方式描述了此功能。

ISO 9899:2011

7.24.2.4 strncpy 函数

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

strncpy 函数将不超过 n 个字符(不复制空字符后的字符)从 s2 指向的数组复制到 s1 指向的数组。如果复制发生在重叠的对象之间,则行为未定义。

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

于 2012-02-27T12:32:23.907 回答
1

strncpy does not want the size of the string to be copied, but the size of the target buffer.

In your case, the target buffer is 1 too short, disabling strncpy to zero-terminate the string. So everything that is behind the string resp. position 18 and is non-zero will be treated as belonging to the string.

Normally, functions taking a buffer size are called with exactly that, i. e.

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

With this and an additional

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

the string will always be 0-terminated.

于 2012-02-27T12:26:03.787 回答
0

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

所以要么事先清除你的目标缓冲区,要么总是添加\0你自己,或者使用strcpy.

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

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

于 2012-02-27T12:13:41.467 回答
0

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

于 2012-02-27T12:20:26.173 回答