我在C中有以下代码:
char a[55] = "hello";
size_t length = strlen(a);
char b[length];
strncpy(b,a,length);
size_t length2 = strlen(b);
printf("%d\n", length); // output = 5
printf("%d\n", length2); // output = 8
为什么会这样?
答案 0 :(得分:9)
必须是'b [长+1]' strlen不包括c字符串末尾的空字符。
答案 1 :(得分:4)
您从未将b
初始化为任何内容。因此它的内容是未定义的。对strlen(b)
的调用可能超出b
的大小并导致未定义的行为(例如崩溃)。
答案 2 :(得分:2)
b
未初始化:它包含程序运行时RAM中的任何内容。
答案 3 :(得分:1)
对于第一个字符串a,长度为5,因为它应该是“hello”有5个字符。
对于第二个字符串,b将其声明为5个字符的字符串,但是不要对其进行初始化,因此它会对字符进行计数,直到找到包含0终止符的字节为止。
更新:在我写完原始答案后添加了以下行。
strncpy(b,a,length);
在这个添加之后,问题是你声明了b的大小长度,而它应该是长度+ 1来为字符串终止符提供空间。
答案 4 :(得分:1)
其他人已经指出你需要为strlen(a)+1
分配b
个字符才能保存整个字符串。
他们已经为你提供了一套用于strncpy
的参数,这些参数会(试图)掩盖这样一个事实,即它不适合手头的工作(或几乎任何其他事实,事实上都被告知) 。你真正想要的只是使用strcpy
。但请注意,当您分配它时,b
也是本地(auto
存储类)变量。将字符串复制到局部变量中很少有用。
大多数情况下,如果您要复制字符串,则需要将其复制到动态分配的存储空间 - 否则,您也可以使用原始文件并完全跳过复制。将字符串复制到动态分配的存储中是很常见的,因此许多库已经包含了一个用于此目的的函数(通常名为strdup
)。如果你的图书馆没有这个,你可以很容易地编写自己的图书馆:
char *dupstr(char const *input) {
char *ret = malloc(strlen(input)+1);
if (ret)
strcpy(ret, input);
return ret;
}
[编辑:我将此命名为dupstr
,因为strdup
(以及以str
开头的任何内容都会保留用于实施。]
答案 5 :(得分:0)
实际上char数组没有被'\ 0'终止,所以strlen无法知道它在何处停止计算字符串的长度,如同 它的语法是int strlen(char * s) - >它返回否。字符串中的字符直到'\ 0'(NULL char) 所以为了避免这种情况,我们必须附加NULL char(b [length] ='\ 0')
否则strlen count字符串中的字符串被传递到遇到NULL计数器