版权声明:本文转载于公众号TeachPlus---C语言面试题---字符串拷贝函数与内存拷贝函数
看看下面的这题:
strcpy()和memcpy()的区别?
答案:
strcpy是字符串拷贝函数
memspy是内存拷贝函数
strcpy()和memcpy()都可以用来拷贝字符串,strcpy()拷贝以’\0’结束,
但memcpy()必须指定拷贝的长度。
本题解析
本题的重点一个是这两个函数的使用,另一个就是关于字符串的结束标志'\0'了。
c语言中的字符串,实际上就是一个字符数组,那么怎么把字符串字符数组区分开来,就得用到字符串的结束标志了。
对于上面的两个问题,大家可以下面的程序作为参考:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
int main()
{
charstr1[20] ="hello world";
charstr2[20];
charstr3[20];
memset(str2,2,20);
memset(str3,2,20);
strcpy(str2,str1);
memcpy(str3,str1,5);
printf("%s\n",str2);
printf("%s\n",str3);
return0;
}
程序输出为:
该程序首先声明了三个字符数组,并且将str1初始化为"hello world";
然后使用memset函数,将str2和str3数组中的内容全部置为2,
以确保内存中没有原来就存在的'\0';
接下来使用strcpy方法将str1 中的内容拷贝到str2中
再将str3使用memcpy直接进行内存拷贝,拷贝五个字节到str3中。
最终输出str2和str3的内容。
从输出的结果大家可以看到,str2的输出是正常的。
因为strcpy在进行拷贝时,自动的将字符串的结束表示进行了拷贝,
printf函数在输出的过程中检测到了'\0'标志则停止输出。
而对于str3则输出了一大串乱码。这是因为 memcpy函数在进行拷贝的时候,
只进行了制定的字节数的内存的拷贝,并没有自动添加'\0'标志,
因此在printf函数输出时,不能够发现结束标志,
所以一直将后面的乱码输出了出来,后面的乱码就是我们在一开始的时
候通过memset函数设置的2了。
相关知识点
针对于字符串类的操作函数,可以考察的方面有很多种,大家可以参考下面的几道面试题:
问:请找出下面代码里的问题:
#include <stdio.h>
intmain(void)
{
charbuff[10];
memset(buff,0,sizeof(buff));
gets(buff);
printf("\n The buffer entered is [%s]\n",buff);
return0;
}
答:上面代码里的问题在于函数gets()的使用,这个函数从stdin接收一个字符串而不检查它所复
制的缓存的容积,这可能会导致缓存溢出。这里推荐使用标准函数fgets()代替。
还有一道题目非常有意思,单看题目来说,可能会被唬住
问:下面是一个简单的密码保护功能,你能在不知道密码的情况下将其破解吗?
# include <stdio.h>
int main(intargc,char*argv[])
{
intflag = 0;
charpasswd[10];
memset(passwd,0,sizeof(passwd));
strcpy(passwd, argv[1]);
if(0 == strcmp("LinuxGeek", passwd))
{
flag = 1;
}
if(flag)
{
printf("\n Password cracked \n");
}
else
{
printf("\n Incorrect passwd \n");
}
return0;
}
答:破解上述加密的关键在于利用攻破strcpy()函数的漏洞。所以用户在向“passwd”缓存输入随
机密码的时候并没有提前检查“passwd”的容量是否足够。所以,如果用户输入一个足够造成缓
存溢出并且重写“flag”变量默认值所存在位置的内存的长“密码”,即使这个密码无法通过验证,
flag验证位也变成了非零,也就可以获得被保护的数据了。例如:
$ ./psswd aaaaaaaaaaaaa
Password cracked
虽然上面的密码并不正确,但我们仍然可以通过缓存溢出绕开密码安全保护。
要避免这样的问题,建议使用 strncpy()函数。
对于字符串来说,比较重要的知识点,第一个时结尾标志'\0'的使用,第二个就是各种操作函数了
对于操作函数来说,可能绝大部分人接触的都是下面这种函数:
总结
gets
//没有边界检查,容易造成溢出
scanf
//不能接收带有空格的字符串
strcpy
//没有边界检查,容易造成溢出
strcmp
//没有边界检查,容易造成溢出
strcat
//没有边界检查,容易造成溢出
但是以上函数都有各自的缺点,因此推荐使用以下函数进行替代:
fgets
strncpy
strncmp
strncat
另外,最好时能够自己实现一下这些函数,这也是面试中常常会考察的一部分
网友评论