strcpy()把"The C of Tranquility"拷贝至str指向的地址上 , 但是str未被初始化 , 所以该字符串可能被拷贝到任意的地方!总之 , strcpy()接受两个字符串指针作为参数 , 可以把指向源字符串的第2个指针声明为指针、数组名或字符串常量;而指向源字符串副本的第1个指针应指向一个数据对象(如 , 数组) , 且该对象有足够的空间存储源字符串的副本 。记住 , 声明数组将分配存储数据的空间 , 而声明指针只分配存储一个地址的空间 。
strcpy()的更多属性
strcpy()函数还有两个有用的属性 。第一 , strcpy()的返回类型是char * , 该函数返回的是第1个参数的值 , 即一个字符的地址 。第二 , 第1个参数不必指向数组的开始 。这个属性可用于拷贝数组的一部分 。程序清单11.26演示了该函数的这两个属性 。
/* copy2.c -- strcpy() demo */#include <stdio.h>#include <string.h>// declares strcpy()#define WORDS"beast"#define SIZE 40int main(void){const char * orig = WORDS;char copy[SIZE] = "Be the best that you can be.";char * ps;puts(orig);puts(copy);ps = strcpy(copy + 7, orig);puts(copy);puts(ps);return 0;}
下面是该程序的输出:
beastBe the best that you can be.Be the beastbeast
注意 , strcpy()把源字符串中的空字符也拷贝在内 。在该例中 , 空字符覆盖了copy数组中that的第1个t 。注意 , 由于第1个参数是copy + 7 , 所以ps指向copy中的第8个元素(下标为7) 。因此puts(ps)从该处开始打印字符串 。
文章插图
The strcpy() function uses pointers.
更谨慎的选择:strncpy()
strcpy()和strcat()都有同样的问题 , 它们都不能检查目标空间是否能容纳源字符串的副本 。拷贝字符串用strncpy()更安全 , 该函数的第3个参数指明可拷贝的最大字符数 。程序copy3.c用strncpy()代替程序copy1.c中的strcpy() 。为了演示目标空间装不下源字符串的副本会发生什么情况 , 该程序使用了一个相当小的目标字符串(共7个元素 , 包含6个字符) 。
/* copy3.c -- strncpy() demo */#include <stdio.h>#include <string.h>/* declares strncpy() */#define SIZE 40#define TARGSIZE 7#define LIM 5char * s_gets(char * st, int n);int main(void){char qwords[LIM][TARGSIZE];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{strncpy(qwords[i], temp, TARGSIZE - 1);qwords[i][TARGSIZE - 1] = '0';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 // must have words[i] == '0'while (getchar() != 'n')continue;}return ret_val;}
下面是该程序的运行示例:Enter 5 words beginning with q:strncpy(target, source, n)把source中的n个字符或空字符之前的字符(先满足哪个条件就拷贝到何处)拷贝至target中 。因此 , 如果source中的字符数小于n , 则拷贝整个字符串 , 包括空字符 。但是 , strncpy()拷贝字符串的长度不会超过n , 如果拷贝到第n个字符时还未拷贝完整个源字符串 , 就不会拷贝空字符 。所以 , 拷贝的副本中不一定有空字符 。鉴于此 , 该程序把n设置为比目标数组大小少1(TARGSIZE-1) , 然后把数组最后一个元素设置为空字符:
quack
quadratic
quisling
quota
quagga
Here are the words accepted:
quack
quadra
quisli
quota
quagga
/* compare.c -- this will work */#include <stdio.h>#include <string.h>// declares strcmp()#define ANSWER "Grant"#define SIZE 40char * s_gets(char * st, int n);int main(void){char try[SIZE];puts("Who is buried in Grant's tomb?");s_gets(try, SIZE);while (strcmp(try,ANSWER) != 0){puts("No, that's wrong. Try again.");s_gets(try, SIZE);}puts("That's right!");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 // must have words[i] == '0'while (getchar() != 'n')continue;}return ret_val;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- C语言的自定义输入和输出的三种方法
- 旧硬盘应该如何处理,阿卡西斯的这款雷电3硬盘盒给出了答案
- 编写C程序控制LED
- 还不知道MySQL怎么给字符串加索引?
- C语言的指针与多维数组
- 架构大更新的英特尔Rocket Lake处理器可将频率提升至5.0GHz
- 被蛇咬伤的处理方法 被蛇咬伤应该怎么处理?
- 使用pandas处理时间变量
- C语言的数组的构建与打印
- 驾考5次不过咋处理?