奇怪的反应
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 打印到那个点为止的字符。
我只是 运行 这段代码,我得到的 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 打印到那个点为止的字符。