目录
求字符串长度
strlen函数
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char* p = "abcdefg";
- printf("%d\n", strlen(p));
- return 0;
- }
2)模拟实现strlen函数
- #include<stdio.h>
- #include<string.h>
- size_t my_strlen(const char* str)
- {
- char* start = str;
- while (*str != '\0')
- {
- str++;
- }
- return str - start;//指针间的差值表示其之间元素的个数
- }
- int main()
- {
- char* p = "abcdefg";
- printf("%d\n",my_strlen(p));//链式访问
- return 0;
- }
长度不限制的字符串函数
strcpy
使用:
1)库函数调用
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[20] = "abcd";
- char arr2[10] = "defgh";
- printf("%s", strcpy(arr1, arr2));
- return 0;
- }
2)模拟实现
char* strcpy(char * destination, const char * source );
- #include<stdio.h>
- #include<assert.h>
- char* my_strcpy(char* dest, const char* src)
- {
- assert(dest && src);//断言,判断dest , src是否为空指针
- char* ret = dest;
- while (*dest++ = *src++)//操作符优先级++高于* *src为'\0'赋给*dest时,此时判断为假
- // ,跳出循环
- {
- ;//空语句,为了提高代码的可读性和美观
- }
- return ret;
- }
- int main()
- {
- char arr1[20] = "abcd";
- char arr2[10] = "defgh";
- printf("%s", my_strcpy(arr1, arr2));
- return 0;
- }
strcat函数
char * strcat ( char * destination, const char * source );
注:
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[20] = "abcd";
- char arr2[10] = "defgh";
- printf("%s", strcat(arr1, arr2));
- return 0;
- }
2)模拟实现strcat函数
char * strcat ( char * destination, const char * source );
- #include<stdio.h>
- #include<assert.h>
- char* my_strcat(char* dest, const char* src)
- {
- assert(dest && src);//断言
- char* ret = dest;
- while (*dest != '\0')//找到dest的'\0',再进行延长。
- dest++;
- while (*dest++ = *src++)
- {
- ;
- }
- return ret;
- }
- int main()
- {
- char arr1[20] = "abcd";
- char arr2[10] = "defgh";
- printf("%s", my_strcat(arr1, arr2));
- return 0;
- }
strcmp函数
使用:
1)函数调用
- #include<stdio.h>
- #include<string.h>
-
- int main()
- {
- char* p1 = "asdfgh";
- char* p2 = "abcdef";
- printf("%d\n",strcmp(p1, p2));
- return 0;
- }
因为‘s’ > 'b' 返回 大于0的数字
2)模拟实现strcmp函数
int strcmp ( const char * str1, const char * str2 );
- #include<stdio.h>
- #include<assert.h>
- int my_strcmp(const char* str1, const char* str2)
- {
- assert(str1 && str2);
- while ((*str1 == *str2)&&(*str1)&&(*str2))//判断字符串每个字符是否相等和字符串是否结束
- {
- str1++;
- str2++;
- }
- if ((*str1=='\0')&&(*str2 == '\0'))//判断相等的情况
- {
- return *str1 - *str2;
- }
- else//判断不相等
- return *str1 - *str2;
-
- }
- int main()
- {
- char* p1 = "asdfgh";
- char* p2 = "abcdef";
- printf("%d\n",my_strcmp(p1, p2));
- return 0;
- }
长度受限制的字符串函数
strncpy函数
- #include<stdio.h>
- #include<string.h>
-
- int main()
- {
- char arr1[20] = "asdfhj";
- char arr2[20] = "abcdef";
- strncpy(arr1, arr2, 5);
- printf("%s", arr1);
- return 0;
- }
2)模拟实现strncpy
- #include<stdio.h>
- #include<assert.h>
- #define M_SIZE 20
- char* my_strncpy(char* dest, const char* src, size_t num)
- {
- char* ret = dest;
- while ((num--)&& (*dest++ = *src++))
- {
- ;
- }
- return ret;
- }
- int main()
- {
- char arr1[M_SIZE] = "asdfhj";
- char arr2[M_SIZE] = "abcdef";
- printf("%s",my_strncpy(arr1, arr2, 5));
- return 0;
- }
strncat函数
注:
strncmp函数
字符串查找函数
strstr函数
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[20] = "i will have order !";
- char arr2[10] = "will";
- char *p = strstr(arr1, arr2);
- printf("%s", p);
- return 0;
- }
2)模拟实现
- #include<stdio.h>
- #include<assert.h>
- char* my_strstr(char* str1, char* str2)
- {
- assert(str1 && str2);
- char* s1 = NULL;
- char* s2 = NULL;
- char* cp = str1;
- //注意回退
- while (*cp)
- {
- s1 = cp;
- s2 = str2;
- while ((*s1 == *s2)&&(*s2)!='\0'&&*s1)
- {
- s1++;
- s2++;
- }
- if (*s2 == '\0')
- return cp;
- cp++;
- }
- return NULL;
- }
- int main()
- {
- char arr1[20] = "iwillhavetheorder!";
- char arr2[20] = "wil";
- char* p = my_strstr(arr1, arr2);
- if (p != NULL)
- puts(p);
- else
- puts("找不到");
- return 0;
- }
strtok函数
char * strtok ( char * str, const char * delimiters );
注:
1)strtok函数会根据所提供的字符串分割str1字符串,遇到分割点自动分割,末尾加上'\0'字符,并记录‘\0'位置,
2)下次分割时参数部分应该为(NULL,分割的字符串)
3)使用时除第一次使用str1外,其余使用的都是NULL参数
使用:
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[] = "i will have the order !";
- char div[] = " ";
- char* ret = NULL;
- for (ret = strtok(arr1,div); ret != NULL; ret = strtok(NULL, div))
- {
- printf("%s\n", ret);
- }
- return 0;
- }
错误信息报告
strerro函数
注:
1)调用库函数时,如果产生错误就会显示错误的信息
2)需要引入全局变量,只需包含头文件#include<errno.h>
3)函数调用strerror(errno);
使用:
- #include<errno.h>
- #include<stdio.h>
- int main()
- {
- FILE* fp = fopen("test.text", "r");//打开文件
- if(fp==NULL)
- printf("%s\n", strerror(errno));//打印错误信息
-
- fclose(fp);//关闭文件
- fp=NULL;
- return 0;
- }
perror函数
注:
1.错误码转化为错误信息
2.自动打印错误信息
- #include<stdio.h>
- #include<errno.h>
- int main()
- {
- //打开文件
- FILE* fp = fopen("test.t", "r");
- if (fp == NULL)
- {
- perror("fopen");//传入的是字符串
- return 1;//结束main函数
- }
- //写数据
-
- //关闭文件
- fclose(fp);
- fp = NULL;
- return 0;
- }
字符操作函数
ctype.h提供了如下字符处理函数;
int isalnum(int c):检查字符是否为数字或字母;(0~9,a~z,A~Z)
int isalpha(int c):检查字符是否为字母;(a~z, A~Z)
int iscntrl(int c):检查字符是否为控制字符;(八进制000~037以及177的字符)
int isdigit(int c):检查字符是否为十进制数字;(0~9)
int isgraph(int c):检查字符是否为图形表示,依赖于使用语言的环境;0~9,a~z,A~Z,以及标点符号)
int islower(int c):检查字符是否为小写的字母;(a~z)
int isprint(int c):检查字符是否为可打印的;(数字、字母、标点符号、空白字符)
int ispunct(int c):检查字符是否为标点符号;(! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~等)
int isspace(int c):检查字符是否为空白字符;(TAB、换行、垂直TAB、换页、回车、空格)
int isupper(int c):检查字符是否为大写字母;(A~Z)
int isxdigit(int c):检查字符是否为十六进制数字;(0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f)
int tolower(int c):转化字符为小写字母;
int toupper(int c):转化字符为大写字母;
这些函数参数均为int类型,事实上仅能传递EOF或者unsigned char类型兼容的;其他值均会失败返回0。
- #include<stdio.h>
- #include<ctype.h>
- //大小写转换
- int main()
- {
- char ch[] = "asSFAvaasRBeB";
- int i = 0;
- while (ch[i] != '\0')
- {
- if (islower(ch[i]))
- ch[i] = toupper(ch[i]);
- else
- if (isupper(ch[i]))
- ch[i] = tolower(ch[i]);
- i++;
- }
- printf("%s", ch);
- return 0;
- }
内存函数
memcpy
void* memcpy(void* dest,const void* src,size_t num);
注:
1)memcpy可处理内存分配不冲突的
使用:
1)调用:
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
- int arr2[10] = { 0 };
- memcpy(arr2, arr1, 24);
- for (int i = 0; i < 10; i++)
- printf("%d ", arr2[i]);
- return 0;
- }
2)模拟实现
- #include<stdio.h>
- #include<assert.h>
-
- void* my_memcpy(void* dest, const void* src, size_t num)
- {
- assert(dest && src);
- void* start = dest;
- //强制类型转换为char*型
- while (num--)
- {
- *((char*)dest) = *((char*)src);
- src = (char*)src + 1;//用后置++的,由于操作符优先级的问题容易错误
- dest = (char*)dest + 1;
- }
- return start;
- }
-
- int main()
- {
- int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
- int arr2[10] = { 0 };
- my_memcpy(arr2, arr1, 24);
- for (int i = 0; i < 10; i++)
- printf("%d ", arr2[i]);
- return 0;
- }
memmove
void* my_memmove(void* dest, void* src, size_t num)
注:
1)memmove可处理内存冲突的问题
使用:
1)调用
略
2)模拟实现
关键是要解决内存覆盖的问题
注:顺序或逆序只针对src。
其余情况顺逆皆可
当dest<src按顺序排列
当dest>=src时逆序排列
- #include<stdio.h>
- #include<assert.h>
- void* my_memmove(void* dest, void* src, size_t num)
- {
- assert(dest && src);
- void* start = dest;
- //强转为char*
- while (num--)
- {
- if (dest < src)//顺序替换
- {
- *(char*)dest = *(char*)src;
- dest = (char*)dest + 1;
- src = (char*)src + 1;
- }
- else//逆序替换
- *((char*)dest + num) = *((char*)src + num);
- }
- return start;
- }
- int main()
- {
- int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
- my_memmove(arr + 3, arr, 16);//1,2,3,1,2,3,4,8,9,0
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", arr[i]);
- }
- return 0;
- }
memcmp
int my_memcmp(const void* str1,const void* str2, size_t num);
相同返回0
str1>str2 返回1
stsr1<str2 返回-1
- int main()
- {
- int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
- int arr2[] = { 1,2,5,4,6,8,6,6,5,6,7 };
- int ret = memcmp(arr1, arr2, 20);
- printf("%d\n", ret);
- return 0;
- }
模拟实现
int my_memcmp(const void* str1,const void* str2, size_t num);
- int my_memcmp(const void* str1,const void* str2, size_t num)
- {
- assert(str1 && str2);
- while (num--)
- {
- if (*(char*)str1 == *(char*)str2)
- {
- str1 = (char*)str1 + 1;
- str2 = (char*)str2 + 1;
- }
- else
- return *(char*)str1 - *(char*)str2;
- }
- return *(char*)str1 - *(char*)str2;
- }
- int link(int ret)
- {
- if (ret > 0)
- return 1;
- else if (ret == 0)
- return 0;
- else
- return -1;
- }
- int main()
- {
- int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
- int arr2[] = { 6,3,5,6,8,9,7,1,0 };
- int ret = my_memcmp(arr1, arr2, 20);
- printf("%d\n",link(ret));
- int ret2 = memcmp(arr1, arr2, 20);
- printf("%d\n%d", ret,ret2);
-
- return 0;
- }
-
memset
void* memset(void* ptr,int value,size_t num)
以字节为单位设置内存
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- int arr[20] = { 0 };
-
- memset(arr, 1, 10);//前10个字节设置为1
- return 0;
- }
没了