#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
char str[5]={'\0'};
printf("Initial length before passing = %ld\n",strlen(str));
input(str);
printf("Received string = %s\n",str);
printf("Length after getting input(calling function) = %ld\n",sizeof(str));
}
input(char * buffer)
{
puts("Enter something: ");
printf("Initial length after passing = %ld\n",strlen(buffer));
if ( fgets(buffer, sizeof(buffer), stdin) == NULL )
return -1;
else
{
printf("Length after getting input(called function)= %ld\n",strlen(buffer));
return 0;
}
}
Initial length before passing = 0
Enter something:
Initial length after passing = 0
hello
Length after getting input(called function)= 6
Received string = hello
Length after getting input(calling function) = 5
Initial length before passing = 0
Enter something:
Initial length after passing = 0
helloooooo
Length after getting input(called function)= 7
Received string = hellooo
Length after getting input(calling function) = 5
为什么在我提供不同的输入时会打印不同的长度?
答案 0 :(得分:2)
strlen
应该使用C字符串,即以\0
结尾的char数组。定义时:
char str[5];
str
包含垃圾,您很幸运地称strlen
没有导致分段错误。
答案 1 :(得分:1)
char str[5]; printf("Initial length before passing = %ld\n",strlen(str));
strlen
返回指定字符串的长度,而不是缓冲区的大小。你没有将str
初始化为任何东西,所以它充满了垃圾。 strlen
将返回垃圾的“长度”,这可能是任何东西。
答案 2 :(得分:1)
1)在输出1&amp; 2当我为5个字符分配空间时,为什么初始长度为6?
由于您声明了strlen(str)
但未向其中添加任何内容,因此您的第一个char str[5]
调用实际上并未定义。所以内容是谁知道什么。 strlen(str)
返回6的事实意味着内存中恰好有6个非零字符,从地址str
开始,然后才遇到0。
2)为什么在传递之前和传入输出1和输出2之后字符串的长度是不同的?
在获得随机内存内容的长度为6之后,您将某些内容加载到字符串缓冲区中并将其终止。所以长度变成了真实的东西。
3)在输出2中,当我只分配较少的空间时,为什么“输入后的长度(称为函数)= 7”?
因为你实际上用更长的字符串(长度为7)覆盖了你分配的空间。你很幸运,在这种情况下程序没有崩溃。
在C中声明缓冲区时,例如:
char str[5];
它所做的只是告诉编译器你要保留5个字节的空间来做某事,它使你有权使用那个空间而只有str
的空间。它不一定在缓冲区中有任何东西可以启动,除非你把它放在那里,并且它不会阻止你写的比你声明的更多。
请注意str[5]
不足以保持“hello”,因为C中的字符串是零终止的。因此,您需要一个大小为N + 1的字符缓冲区来保存大小为N的字符串。当您在C中溢出缓冲区时,您的结果将变得不稳定且不可预测。