#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
/**
*date: 2019.6.11
*描述:要求用户输入以q开头的单词,该程序把输入拷贝到一个临时数组中,如果第一个字母是q,程序调用strcpy()把
*整个字符串从临时数组中拷贝至目标数组中
*/
#define SIZE 40
#define LIM 5
char* s_gets(char* st, int n);
int main(int argc, char *argv[]) {
char qwords[LIM][SIZE];
char temp[SIZE];
int i = 0;
printf("Enter %d words beginning with q:\n", LIM);
while (i < LIM && s_gets(temp, SIZE))
{
if(temp[0] != 'q')
{
printf("%s doesn't begin with q\n", temp);
}
else
{
strcpy(qwords[i],temp);
i++;
}
}
puts("Here are the words accepted:");
for ( i = 0; i < LIM; i++)
{
puts(qwords[i]);
}
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if(ret_val)
{
while (st[i] != '\n' && st[i] != '\0')
{
i++;
}
if (st[i] == '\n')
{
st[i] = '\0';
}
else
{
while (getchar() != '\n')
continue;
}
}
return ret_val;
}
运行结果:
Enter 5 words beginning with q:
quit
quiet
quick
quiz
test
test doesn't begin with q
quote
Here are the words accepted:
quit
quiet
quick
quiz
quote
下面写一个小的测试程序来对比一下strcpy与strncpy
1.strcpy()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char test1[] = "helloworld";
char test2[] = "aaaaaa";
printf("test1:0x%x,test2:0x%x\n",test1,test2);
printf("strlen(test1):%d,strlen(test2):%d\n",strlen(test1),strlen(test2));
strcpy(test2,test1);
//strncpy(test2,test1,strlen(test2) - 1);
//test2[strlen(test2) - 1] = '\0';
puts(test1);
puts(test2);
return 0;
}
运行结果:
test1:0x62fe30,test2:0x62fe20
strlen(test1):10,strlen(test2):6
helloworld
helloworld
从该程序中可以看到,若目标字符串的空间小于源字符串的空间,使用strcpy,会导致缓冲区溢出。
test2[]的大小为6,但是在调用strcpy后,输出的字符串大小为10,很明显,占用了别的内存空间。
2.strncpy
strncpy()与strcpy()的不同之处在于:它会检查目标空间是否能够容纳原字符串的副本。该函数的第三个参数指明可拷贝的最大字符数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char test1[] = "helloworld";
char test2[] = "aaaaaa";
printf("test1:0x%x,test2:0x%x\n",test1,test2);
printf("strlen(test1):%d,strlen(test2):%d\n",strlen(test1),strlen(test2));
//strcpy(test2,test1);
strncpy(test2,test1,strlen(test2) - 1);
test2[strlen(test2) - 1] = '\0';
puts(test1);
puts(test2);
return 0;
}
运行结果:
test1:0x62fe30,test2:0x62fe20
strlen(test1):10,strlen(test2):6
helloworld
hello