奇怪的反应

Strange strncpy response

我只是 运行 这段代码,我得到的 n=1 不是我期望得到的。你能解释一下为什么会这样吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXRIGA 11
int main()
{
    char s[MAXRIGA+2];
    char a[MAXRIGA]="pippo";
    strncpy(s, a, 1); //       n=1
    printf("%s", s);
    return 0;
}

returns

pF

相反,如果 n=2 或更多,我会得到我想要的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXRIGA 11
int main()
{
    char s[MAXRIGA+2];
    char a[MAXRIGA]="pippo";
    strncpy(s, a, 2); //       n=2
    printf("%s", s);
    return 0;
}

returns

pi

来自man strncpy

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

您只从源字符串中复制了一个字节,这不是 null-terminator。所以你在这里得到了一个未定义的行为,因为试图打印一个 non-terminated 字符串。 n=2 也是如此, 似乎 意外工作。

strncpy 不会将空终止符附加到字符串上。使用strncpy.

后需要手动添加

像这样:

strncpy(s, a, 1); //       n=1
s[1]=0;
printf("%s", s);

F(来自 pF)只是任意字符,它仍然恰好驻留在内存中找到任何空终止符之前遇到的位置。严格来说,您的代码应该产生缓冲区溢出错误或访问冲突错误。

在使用 strncpy 后添加空终止符,您的问题就会消失:)

因为您没有初始化数组 s 它包含随机值。 C 中的字符串以 NULL 字符结尾,因此当您使用 "pippo" 初始化数组 a 时,它包含的值是:

offset | 0 | 1 | 2 | 3 | 4 |  5 |
value  | p | i | p | p | o | [=10=] |

当您调用 printf 时,它需要确定字符串的结尾位置,它通过打印字符直到到达终止 NULL 来完成此操作。如果 s 包含随机数据并且您只复制单个字符,那么 printf 将打印字符串,直到它到达一个恰好为 NULL 的字节。在这种情况下,看起来随机数据的第 3 个字节是 \0,所以 printf 打印到那个点为止的字符。