参考: 参考1 参考2
问题提出
sizeof(str) 和 strlen(str) 的区别?strcpy 和 strncpy 的区别?strcpy 和 strncpy 函数为什么要返回dest的副本?strcpy 和 strncpy 函数的缺陷有哪些?你如何解决?有替代函数吗?
问题解决
sizeof(str) 和 strlen(str) 的区别?
sizeof(str) 会计算str所占总空间的字节数,strlen(str)会计算字符串的有效长度,不包括’\0’。
#include<iostream>
using namespace std
;
int main()
{
char str
[] = { "hello hello" };
int len1
= strlen(str
);
int len2
= sizeof(str
);
cout
<< len1
<< endl
;
cout
<< len2
<< endl
;
system("pause");
return 0;
}
strcpy 和 strncpy 的区别?
区别是strncpy有参数控制拷贝的个数,不像strcpy,strncpy不会向dest追加结束标记’\0’
strcpy特点:
将src拷贝到dest中,包括’\0’字符为避免溢出dest指向的空间应该足够大能够放的下src
strncpy特点:
如果src的前n个字节不含’\0’字符,则结果不会以’\0’字符结束。如果src的长度小于n个字节,则以’\0’填充dest直到复制完n个字节。如果src中有’\0’,例如:“abc\0def” 则只会复制abcsrc和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
strcpy 和 strncpy 函数为什么要返回dest的副本?
为了实现函数连级使用 例如:strcpy(str3, strcpy(str1,str2))
strcpy 和 strncpy 函数的缺陷有哪些?你如何解决?有替代函数吗?
strcpy函数缺陷:
要程序员保证dest大小能够存放src包括’\0’,一旦dest空间不够会在别的内存中写入,很危险。可能有覆盖问题
strncpy函数缺陷:
如果src的前n个字符不包含’\0’字符,strncpy函数不会在末尾补上’\0’,打印时会有乱码。如果src的长度小于n个字节,则以’\0’填充dest直到复制完n个字节,如果n远大于src这会导致效率问题。可能有覆盖问题
解决缺陷的方法
正确使用这两个函数: 1.使用strcpy时人工确定dest大小足够 2.使用strncpy时,确保 n = dest - 1 例如: strncpy(path, src, sizeof(path) - 1); path[sizeof(path) - 1] = ‘\0’;
使用替代函数:memmove(),解决src可能被覆盖问题
strcpy()实现
char* my_strcpy(char* dest
, const char* src
)
{
char* save
= dest
;
while ((*dest
++ = *src
++) != '\0');
return save
;
}
strncpy() 实现
char* my_strncpy(char* dest
, const char* src
, size_t count
)
{
char* save
= dest
;
while (count
--)
{
if (*src
!= '\0') *dest
++ = *src
++;
else *dest
++ = '\0';
}
return save
;
}
memcpy()实现
void* my_memcpy(void* dest
, const void* src
, size_t count
)
{
assert(dest
!= nullptr && src
!= nullptr);
char* p
= (char*)dest
;
char* q
= (char*)src
;
if (p
== q
) return p
;
while (count
--)
{
*p
++ = *q
++;
}
return dest
;
}
memmove()实现
void* my_memmove(void* dest
, const void* src
, size_t count
)
{
assert(dest
!= nullptr && src
!= nullptr);
if (dest
< src
)
{
char* p
= (char*)dest
;
char* q
= (char*)src
;
while (count
--)
{
*p
++ = *q
++;
}
}
else
{
char* p
= (char*)dest
+ count
;
char* q
= (char*)src
+ count
;
while (count
--)
{
*--p
= *--q
;
}
}
return dest
;
}
测试用例
int main()
{
char dest
[20];
my_strcpy(dest
, str
);
my_strncpy(dest
, str
, 15);
cout
<< dest
<< endl
;
char s1
[] = "123456789";
char s2
[] = "123456789";
my_memcpy(s1
+ 2, s1
, 5);
cout
<< "my_memcpy: " << s1
<< endl
;
my_memmove(s2
+ 2, s2
, 5);
cout
<< "my_memmove: " << s2
<< endl
;
system("pause");
return 0;
}