<C> 字符串相关的函数
一.strlen
1.头文件:#include<string.h>
2.返回值:(无符号int)字符串长度
3.作用:计算字符串的长度
4.与sizeof的区分:sizeof是求大小的 这里用一道例题来说明
1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 char str1[] = "abcde"; 7 int a = strlen(str1); //5 8 int b = sizeof(str1); //6 9 10 char* str2 = "abcde"; 11 int c = strlen(str2); //5 12 int d = sizeof(str2); //4 在32位操作系统中 指针的大小固定就是4 13 14 return 0; 15 }
5.长度函数输出实现练习
1 #include<stdio.h> 2 #include<string.h> 3 4 size_t MyStrlen(char* str); 5 6 int main() 7 { 8 char str[] = "abcd"; 9 int a = MyStrlen(str); 10 11 printf("%d\n",a); 12 return 0; 13 } 14 15 size_t MyStrlen(char* str) 16 { 17 size_t count = 0; 18 if(*str == NULL) 19 { 20 return -1; 21 } 22 23 while(*str != '\0') 24 { 25 count ++; 26 *str ++; 27 } 28 29 return count; 30 }
注:size_t是无符号int类型
二.strcpy(有点不安全)
1.头文件:#include<string.h>
2.返回值:目标字符串的首地址
3.使用方法:strcpy(目标,源);
例:
1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 char* str = "abcd"; 7 char str1[5]; 8 char* p = strcpy(str1,str); 9 10 printf("%s\n",p); 11 return 0; 12 }
需要注意的是:在定义目标字符串的时候 所给的空间应该是足够大的 不够大的话会崩 目标一定要大于等于源!!!
4.作用:将第二个参数(源字符串中的内容)拷贝到第一个(目标数组)中 并且返回目标字符串的首元素地址
5.拷贝函数实现练习
1 #include<stdio.h> 2 #include<string.h> 3 4 char* MyStrcpy(char* str1,const char* str2); 5 6 int main() 7 { 8 char str1[5]; //不写方括号它就是个变量啊! 9 char* str2 = "abcd"; 10 11 char* p = MyStrcpy(str1,str2); 12 13 printf("%s\n",p); 14 return 0; 15 } 16 17 char* MyStrcpy(char* str1,const char* str2) 18 { 19 char* p = str1; 20 21 if(str1 == NULL || str2 == NULL) //也得判断str1是不是空的啊 因为它也应该是有空间的! 22 { 23 return NULL; 24 } 25 else if(strlen(str1)+1 < strlen(str2)+1) 26 { 27 return NULL; 28 } 29 30 while(*str2 != '\0') 31 { 32 *str1 ++ = *str2 ++; 33 } 34 35 *str1 = '\0'; 36 return p; 37 }
三.strcpy_s
1.使用方法:strcpy_s(目标,目标空间大小,源);
1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 char* str = "abcd"; 7 char str1[5]; 8 9 strcpy_s(str1,5,str); 10 11 printf("%s\n",str1); 12 13 return 0; 14 }
注:目标空间大小要和前面目标的大小保持一致
2.返回值:(int类型)0代表成功拷贝
四.strncpy
1.使用方法:strncpy(目标,源,拷贝个数);
2.返回值:char*
3.函数实现:
1 #include<stdio.h> 2 #include<string.h> 3 4 char* MyStrncpy(char* str1,const char* str2,int n); 5 6 int main() 7 { 8 char str1[5]; 9 char* str2 = "abcd"; 10 int n = 2; 11 12 char* p = MyStrncpy(str1,str2,n); 13 14 printf("%s\n",p); 15 } 16 17 char* MyStrncpy(char* str1,const char* str2,int n) 18 { 19 char* p = str1; 20 int i; 21 22 if(str1 == NULL || str2 ==NULL) 23 { 24 return NULL; 25 } 26 else if(strlen(str1)+1 < strlen(str2)+1) 27 { 28 return NULL; 29 } 30 31 for(i=0;i<n;i++) 32 { 33 *str1 ++ = *str2 ++; 34 } 35 36 *str1 = '\0'; 37 return p; 38 }
五.strcat
1.使用方法:strcat(目标,源);
2.作用:字符串拼接 把源拼接到目标的后面
3.返回值:char*
4.函数实现:
1 #include<stdio.h> 2 #include<string.h> 3 4 char* MyStrcat(char* str1,const char* str2); 5 6 int main() 7 { 8 char str1[10] = "abc"; 9 char* str2 = "def"; 10 11 char* p = MyStrcat(str1,str2); 12 printf("%s\n",p); 13 14 return 0; 15 } 16 17 char* MyStrcat(char* str1,const char* str2) 18 { 19 char* p = str1; 20 21 if(str1 == NULL || str2 == NULL) 22 { 23 return NULL; 24 } 25 26 while(*str1 != '\0') 27 { 28 *str1 ++; 29 } 30 while(*str2 != '\0') 31 { 32 *str1++ = *str2++; 33 } 34 *str1 = '\0'; 35 36 return p; 37 }
六.strcat_s
1.使用方法:strcat_s(目标,源,目标大小);
1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 char str1[10] = "abc"; 7 char* str2 = "abcd"; 8 9 int p = strcat_s(str1,sizeof(str1),str2); 10 printf("%d\n",p); 11 12 return 0; 13 }
注:剩下的空间应该大于源的空间
2.返回值:(int类型) 0代表拼接成功
七.strncat
1.功能:拼接函数
2.使用方法:strncat(目标,源,拼接个数);
3.函数实现:
1 #include<stdio.h> 2 #include<string.h> 3 4 char* MyStrncat(char* str1,const char* str2,int count); 5 6 int main() 7 { 8 char str1[10] = "abcd"; 9 char* str2 = "12345"; 10 int count = 3; 11 12 printf("%s\n",MyStrncat(str1,str2,count)); 13 14 return 0; 15 } 16 17 char* MyStrncat(char* str1,const char* str2,int count) 18 { 19 int i; 20 char* p = str1; 21 while(*str1 != '\0') 22 { 23 str1++; 24 } 25 26 for(i=0;i<count;i++) 27 { 28 *str1++ = *str2++; 29 } 30 31 *str1 = '\0'; 32 33 return p; 34 }
八.strcmp
1.功能:字符串的比较 实际上是一位一位的比较ASCⅡ码的值
注:这里有一个需要注意的问题 一定会有高贵的人们想 为什么这里不能用if来比较两个字符串呢
假如我们定义三个字符串:char * str1 = "abc"; char* str2 = "abc"; char str3[] = "abcd";
str1和str2是栈区中申请的一个指针 这个指针指向的是字符常量区 而str3是栈区中申请的字符数组 里面存的是abc和\0
而且像这样if(str1 == str2)比较的本质 比较的是地址
2.返回值:int类型
①0 相同
②1 str1>str2
③-1 str1<str2
3.使用方法:strcmp(str1,str2);
4.实现练习:
1 #include<stdio.h> 2 3 int MyStrcmp(const char* str1,const char* str2); 4 int MyStrcmp1(const char* str1,const char* str2); 5 6 int main() 7 { 8 printf("%d\n",MyStrcmp("aaa","aaa")); 9 printf("%d\n",MyStrcmp("aa","aaa")); 10 printf("%d\n",MyStrcmp("aaa","aa")); 11 printf("%d\n",MyStrcmp("ab","aaa")); 12 13 printf("%d\n",MyStrcmp1("aaa","aaa")); 14 printf("%d\n",MyStrcmp1("aa","aaa")); 15 printf("%d\n",MyStrcmp1("aaa","aa")); 16 printf("%d\n",MyStrcmp1("ab","aaa")); 17 18 return 0; 19 } 20 21 int MyStrcmp(const char* str1,const char* str2) 22 { 23 //遍历str1和str2 一一比较 重点在于放在一个循环里遍历 还不知道循环次数 24 while(*str1 != '\0' && *str2 != '\0') 25 { 26 if(*str1 == *str2) 27 { 28 //如果相等比较下一个 都相等了才能返回0 29 str1++; 30 str2++; 31 } 32 else if(*str1 > *str2) 33 { 34 return 1; 35 } 36 else if(*str1 < *str2) 37 { 38 return -1; 39 } 40 } 41 42 if(*str1 == *str2) 43 { 44 return 0; 45 } 46 else if(*str1 > *str2) 47 { 48 return 1; 49 } 50 else if(*str1 < *str2) 51 { 52 return -1; 53 } 54 55 } 56 57 int MyStrcmp1(const char* str1,const char* str2) 58 { 59 while(*str1 != '\0' || *str2 != '\0') 60 //都到结尾才结束 也就是说两个字符串都走到了'\0' 才出循环也就是说 前面比较过的都是一样的 才能出来 61 { 62 if(*str1 == *str2) 63 { 64 //如果相等比较下一个 都相等了才能返回0 65 str1++; 66 str2++; 67 } 68 else if(*str1 > *str2) 69 { 70 return 1; 71 } 72 else if(*str1 < *str2) 73 { 74 return -1; 75 } 76 } 77 78 return 0; 79 }
这里介绍了两种方法 “||”和“&&”是都可以的 我个人的第一直觉是“||” 更简单啊因为
九.strncmp
1.使用方法:strncmp(str1,str2,比较个数);
2.实现练习:
1 #include<stdio.h> 2 3 int MyStrncmp(const char* str1,const char* str2,int count); 4 5 int main() 6 { 7 printf("%d\n",MyStrncmp("aaa","aaa",2)); 8 printf("%d\n",MyStrncmp("aa","aaa",2)); 9 printf("%d\n",MyStrncmp("aaa","aa",2)); 10 printf("%d\n",MyStrncmp("ab","aaa",2)); 11 12 return 0; 13 } 14 15 int MyStrncmp(const char* str1,const char* str2,int count) 16 { 17 int i; 18 for(i=0;i<count;i++) 19 { 20 if(*str1 == *str2) 21 { 22 str1++; 23 str2++; 24 } 25 else if(*str1 > *str2) 26 { 27 return 1; 28 } 29 else if(*str1 < *str2) 30 { 31 return -1; 32 } 33 } 34 35 return 0; 36 }
如果上面的strcmp你整明白了 这个代码根本就不是问题 就是多了一个灰常简单的for循环的问题 so~easy 码一码试一试
十.atoi
1.头文件:#include<stdlib.h>
2.功能:字符串数字转化成数字 例如:atoi("+123"); //输出结果为123 此时的123已经是一个int型的了
3.实现练习:
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int MyAtoi(const char* str); 5 6 int main() 7 { 8 char* str = "+123"; 9 printf("%d\n",MyAtoi(str)); 10 11 return 0; 12 } 13 14 int MyAtoi(const char* str) 15 { 16 int mark = 1; 17 //mark为1 是正数 为-1 是负数 这样执行到最后的时候 所得的数乘以标记 是正的就是正的 是负的就是负的 18 int value = 0; 19 20 //过滤空格 21 while(*str == ' ') 22 { 23 str ++; 24 } 25 26 if(*str == '+' || *str == '-')//这层判断是不能删的 因为如果你删了外面的循环 例如“a123”就也可以改变mark的值了 27 { 28 if(*str == '+') 29 { 30 mark = 1; 31 } 32 else 33 { 34 mark = -1; 35 } 36 str ++; 37 } 38 39 //循环往复 判断是否为有效数字 一位一位的取数字 40 while(*str >= '0' && *str <= '9') 41 { 42 value = value * 10 + (*str - '0'); 43 //value * 10是用来进位的 '0'的值是48 44 str ++; 45 } 46 47 return mark * value; 48 }
十一.itoa
1.头文件:(这次任性不打了!你肯定能猜出来是啥吧!跟上面的长的那么像!)
2.使用方法:itoa(int类型需要转的数,字符串,进制);
注:当这条语句结束执行完了的时候 输出的就是字符串了
3.实现练习:这里简化一下 我们先不考虑进制的问题(哭出声 我好菜 立一个flag 以后我一定把如何转化进制补上!这么经典!而且朦胧中我记得炒鸡简单)
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 char* MyItoa(int value,char* str); 5 6 int main() 7 { 8 char str[10]; 9 printf("%s\n",MyItoa(123,str)); 10 printf("%s\n",MyItoa(-123,str)); 11 12 return 0; 13 } 14 15 char* MyItoa(int value,char* str) 16 { 17 int i = 1; 18 int temp; 19 char* mark = str; 20 21 //判断正负 把负数变成正数 方便后面进行操作 22 if(value < 0) 23 { 24 *str = '-'; 25 str ++; 26 value = -value; 27 } 28 29 //判断位数 30 temp = value; 31 while(temp >= 10) 32 { 33 temp /= 10; 34 i *= 10; 35 } 36 37 for(i;i>0;i/=10) 38 { 39 *str = value/i%10 + '0'; 40 //把每一位都取出来 存在字符串中 41 str ++; 42 } 43 44 *str = '\0'; 45 //大大方方的给它一个'\0' 让它变成一个成熟的字符串! 46 return mark; 47 }