每一个不曾起舞的日子,都是对生命的辜负。
字符串+内存函数的介绍
1.本章重点
2.函数介绍
2.1 strlen
2.2 strcpy
2.3 strcat
2.4 strcmp
2.5 strncpy
2.6 strncat
2.7 strncmp
2.8 strstr
2.9 strtok
2.10 strerror
2.11 memcpy
2.12 memmove
2.13 memcmp
3. 库函数的模拟实现
3.1 模拟实现strlen(三种方式)
3.2 模拟实现strcpy
3.3 模拟实现strcat
3.4 模拟实现strstr(下一篇扩展KMP算法)
3.5 模拟实现strcmp
3.6 模拟实现memcpy
3.7 模拟实现memmove
4. 实现一道典型题目
5.总结:
1.本章重点
重点介绍处理字符和字符串的库函数的使用和注意事项
1.求字符串长度
strlen
2.长度不受限制的字符串函数
strcpy
strcat
strcmp
3.长度受限制的字符串函数介绍
strncpy
strncat
strncmp
4.字符串查找
strstr
strtok
5.错误信息报告
strerror
6.字符操作
7.内存操作函数
memcpy
memmove
memset
memcmp
2.函数介绍
2.1 strlen
size_t strlen(const char* str);
字符串已经’\0’作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数(不包含’\0’)
注:
1)参数指向的字符串必须要以’\0’结束。
2)注意函数的返回值为size_t,是无符号的。(易错)
3)学会strlen函数的模拟实现。
#include <stdio.h> int main() { const char* str1 = "abcdef"; const char* str2 = "bbb"; if (strlen(str2) - strlen(str1) > 0) { printf("str2>str1\n"); } else { printf("srt1>str2\n");//打印 } return 0; }
2.2 strcpy
char* strcpy(char * destination, const char * source );
将source的字符全部复制给destination,返回值为复制之后的destination的地址
注:
1)原字符串必须以’\0’结束。
2)会将source中的0拷贝到destination的空间。
3)目标空间必须足够大,以确保能存放原字符串。
4)目标空间必须可变。
5)学会模拟实现。
2.3 strcat
char* strcat(char* destination,const char* source);
将源字符串的副本追加到目标字符串。终止空字符在destination中被源的第一个字符覆盖,并且包含一个空字符在新字符串的末尾,将两者连接在destination中形成,返回值为连接之后的destination的首地址。
注:
1)源字符串必须以’\0’结束
2)目标空间必须足够大,即destination必须放得下二者之和
3)目标空间必须可修改。
4)字符串自己给自己追加,如何?
答 4):会陷入死循环,在模拟实现中解释
2.4 strcmp
int strcmp(const char* str1, const char* str2);
这个函数开始比较每个字符串的第一个字符。如果它们相等,则继续向后比较,直到字符不同或终止null字符。注:(比较的是ascii码值的大小)
标准规定:
1)第一个字符串大于第二个字符串,则返回大于0的数字
2)第一个字符串等于第二个字符串,则返回0
3)第一个字符串小于第二个字符串,则返回小于0的数字
4)那么如何判断两个字符串?一个字母一个字母比较ascii码值的大小,不相等就截止
2.5 strncpy
char* strncpy(char* destination, const char* source ,size_t num);
比strcpy多了一个长度上的限制,即将source的前num个字符拷贝到destination中。
注:
1)拷贝num个字符从源字符串到目标空间。
2)如果源字符串的长度小于num,则拷贝完字符串之后,在目标的后面追加0,直到num个。
2.6 strncat
char* strncat(char* destination,const char* source,size_t num);
比strcat多了一个长度上的限制,即将source的前num个字符连接到destination上。
int main() { char str1[20]; char str2[20]; strcpy(str1, "To be "); strcpy(str2, "or not to be"); strncat(str1, str2, 6); puts(str1); return 0; }
结果如下:
2.7 strncmp
int strncmp(const char* str1,const char* str2,size_t num);
比较前num个字符二者的大小,比strcmp多了数量上的限制
int main() { char str[][5] = { "R2D2","C3Po","R2A6" }; int n; puts("Looking for R2 astromech droids..."); for (n = 0; n < 3; n++) { if (strncmp(str[n], "R2xx", 2) == 0) { printf("found %s\n", str[n]); } } return 0; }
2.8 strstr
char* strstr(const char*str1,const char* str2);
在字符串str1中查找str2是否在str1内部,即查找子串,若找到,则返回str2在str1处的地址,若找不到,则返回NULL。
2.9 strtok
char* strtok(char* str, const char* sep);
注:
1)sep参数是个字符串,定义了用作分隔符的字符集合 。
2第一个参数指定一个字符串,它包含了0个或多个由sep字符串中一个或者 多个分隔符分割的标记。
3)strtok函数找到str中的下一个标记,并将其用’\0’结尾,返回一个指向这个标记的指针。(strtok会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改)
4)strtok函数的第一个参数不为NULL,函数将找到str中的第一个标记,strtok函数将保存它在字符串中的位置。
5)strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
6)如果字符串不存在更多标记,则返回NULL指针。
//strtok example int main() { char str[] = "- This, a sample string."; char* pch; printf("Splitting string \"%s\" into tokens:\n", str); pch = strtok(str, ",.-"); while (pch != NULL) { printf("%s\n", pch); pch = strtok(NULL, ", .-");//逗号,空格,点,减号 } return 0; //下面的循环方法同样适用: //int main() //{ // const char* sep = "@."; // char email[] = "zhangpengwei@bitejiuyeke.com.net"; // char cp[40] = { 0 };//"zhangpengwei@bitejiuyeke.com" // strcpy(cp, email); // // char* ret = NULL; // for (ret = strtok(cp, sep); // ret != NULL; // ret=strtok(NULL, sep)) // { // printf("%s\n", ret); // } }
结果为:
注:当出现两个及以上分隔符连在一起时,看成一个分隔符即可”
2.10 strerror
char* strerror(int errnum);
strerror的功能是返回错误码,所对应的错误信息。从而找到错误的原因。
//C语言的库函数,在执行失败的时候,都会设置错误码 //0 1 2 3 4 5 6 7 8 #include<errno.h> int main() { /*printf("%s\n", strerror(0)); printf("%s\n", strerror(1)); printf("%s\n", strerror(2)); printf("%s\n", strerror(3)); printf("%s\n", strerror(4)); printf("%s\n", strerror(5));*/ //errno - C语言设置的一个全局的错误码存放的变量 FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { printf("%s\n", strerror(errno)); } else { //一系列操作 } return 0; }
字符分类函数:<ctype.h>
函数 &如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母az或AZ
isalnum 字母或者数字,az,AZ,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符
大小写字母转换函数:
int tolower ( int c );
int toupper ( int c );
int main() { //int a = isspace(' '); //printf("%d\n", a); //int a = isdigit('x'); //printf("%d\n", a); printf("%c\n", tolower('@'));//@ printf("%c\n", tolower('A'));//a printf("%c\n", toupper('b'));//B return 0; }