关键词搜索

源码搜索 ×
×

字符函数和字符串函数

发布2022-01-08浏览576次

详情内容

目录

求字符串长度

strlen

长度不限制的字符串函数

strcpy

strcat

strcmp

长度受限制的字符串函数

strncpy

strncat

srncmp

字符串查找函数

strstr

strtok

错误信息报告

strerror

字符操作

内存操作函数

memcpy

memmove

memset

memcmp


求字符串长度

strlen函数

size_t strlen ( const char * str );
注:
1)字符串已经 '\0' 作为结束标志, strlen 函数返回的是在字符串中 '\0' 前面出现的字符个数(不包
'\0' )
2)参数指向的字符串必须要以 '\0' 结束。
3)注意函数的返回值为 size_t ,是无符号的。
使用
1)调用库函数
  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. char* p = "abcdefg";
  6. printf("%d\n", strlen(p));
  7. return 0;
  8. }

2)模拟实现strlen函数

  1. #include<stdio.h>
  2. #include<string.h>
  3. size_t my_strlen(const char* str)
  4. {
  5. char* start = str;
  6. while (*str != '\0')
  7. {
  8. str++;
  9. }
  10. return str - start;//指针间的差值表示其之间元素的个数
  11. }
  12. int main()
  13. {
  14. char* p = "abcdefg";
  15. printf("%d\n",my_strlen(p));//链式访问
  16. return 0;
  17. }

长度不限制的字符串函数

strcpy

char* strcpy ( char * destination , const char * source );
注:
1)源字符串必须以 '\0' 结束。
2)会将源字符串中的 '\0' 拷贝到目标空间。
3)目标空间必须足够大,以确保能存放源字符串。
4)目标空间必须可变。

使用:

1)库函数调用

  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. char arr1[20] = "abcd";
  6. char arr2[10] = "defgh";
  7. printf("%s", strcpy(arr1, arr2));
  8. return 0;
  9. }

 2)模拟实现

char* strcpy(char * destination, const char * source );

  1. #include<stdio.h>
  2. #include<assert.h>
  3. char* my_strcpy(char* dest, const char* src)
  4. {
  5. assert(dest && src);//断言,判断dest , src是否为空指针
  6. char* ret = dest;
  7. while (*dest++ = *src++)//操作符优先级++高于* *src为'\0'赋给*dest时,此时判断为假
  8. // ,跳出循环
  9. {
  10. ;//空语句,为了提高代码的可读性和美观
  11. }
  12. return ret;
  13. }
  14. int main()
  15. {
  16. char arr1[20] = "abcd";
  17. char arr2[10] = "defgh";
  18. printf("%s", my_strcpy(arr1, arr2));
  19. return 0;
  20. }

strcat函数

char * strcat ( char * destination, const char * source );

注:

1)源字符串必须以 '\0' 结束。
2)目标空间必须有足够的大,能容纳下源字符串的内容。
3)目标空间必须可修改。
使用:
1)调用库函数
  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. char arr1[20] = "abcd";
  6. char arr2[10] = "defgh";
  7. printf("%s", strcat(arr1, arr2));
  8. return 0;
  9. }

2)模拟实现strcat函数

char * strcat ( char * destination, const char * source ); 

  1. #include<stdio.h>
  2. #include<assert.h>
  3. char* my_strcat(char* dest, const char* src)
  4. {
  5. assert(dest && src);//断言
  6. char* ret = dest;
  7. while (*dest != '\0')//找到dest的'\0',再进行延长。
  8. dest++;
  9. while (*dest++ = *src++)
  10. {
  11. ;
  12. }
  13. return ret;
  14. }
  15. int main()
  16. {
  17. char arr1[20] = "abcd";
  18. char arr2[10] = "defgh";
  19. printf("%s", my_strcat(arr1, arr2));
  20. return 0;
  21. }

strcmp函数

int strcmp ( const char * str1 , const char * str2 );
注:

 

使用:

1)函数调用

  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. char* p1 = "asdfgh";
  6. char* p2 = "abcdef";
  7. printf("%d\n",strcmp(p1, p2));
  8. return 0;
  9. }

 因为‘s’ > 'b' 返回 大于0的数字

2)模拟实现strcmp函数

int strcmp ( const char * str1, const char * str2 );

  1. #include<stdio.h>
  2. #include<assert.h>
  3. int my_strcmp(const char* str1, const char* str2)
  4. {
  5. assert(str1 && str2);
  6. while ((*str1 == *str2)&&(*str1)&&(*str2))//判断字符串每个字符是否相等和字符串是否结束
  7. {
  8. str1++;
  9. str2++;
  10. }
  11. if ((*str1=='\0')&&(*str2 == '\0'))//判断相等的情况
  12. {
  13. return *str1 - *str2;
  14. }
  15. else//判断不相等
  16. return *str1 - *str2;
  17. }
  18. int main()
  19. {
  20. char* p1 = "asdfgh";
  21. char* p2 = "abcdef";
  22. printf("%d\n",my_strcmp(p1, p2));
  23. return 0;
  24. }

长度受限制的字符串函数

strncpy函数

char * strncpy ( char * destination , const char * source , size_t num );
注:
1)拷贝 num 个字符从源字符串到目标空间。
2)如果源字符串的长度小于 num ,则拷贝完源字符串之后,在目标的后边追加 0 ,直到 num 个。
使用:
1)调用
  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. char arr1[20] = "asdfhj";
  6. char arr2[20] = "abcdef";
  7. strncpy(arr1, arr2, 5);
  8. printf("%s", arr1);
  9. return 0;
  10. }

 2)模拟实现strncpy

  1. #include<stdio.h>
  2. #include<assert.h>
  3. #define M_SIZE 20
  4. char* my_strncpy(char* dest, const char* src, size_t num)
  5. {
  6. char* ret = dest;
  7. while ((num--)&& (*dest++ = *src++))
  8. {
  9. ;
  10. }
  11. return ret;
  12. }
  13. int main()
  14. {
  15. char arr1[M_SIZE] = "asdfhj";
  16. char arr2[M_SIZE] = "abcdef";
  17. printf("%s",my_strncpy(arr1, arr2, 5));
  18. return 0;
  19. }

 strncat函数

char * strncat ( char * destination , const char * source , size_t num );

注:

1)Appends the first num characters of source to destination, plus a terminating null-character.
2)If the length of the C string in source is less than num, only the content up to the terminating
null-character is copied.

strncmp函数

int strncmp ( const char * str1 , const char * str2 , size_t num );
注:

 字符串查找函数

strstr函数

char * strstr ( const char * str1 , const char * str2 );
根据str2中的字符串在str1中寻找,找到后返回str1中找到的字符串首元素地址,找不到则返回NULL
使用:
1)调用
  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. char arr1[20] = "i will have order !";
  6. char arr2[10] = "will";
  7. char *p = strstr(arr1, arr2);
  8. printf("%s", p);
  9. return 0;
  10. }

 2)模拟实现

  1. #include<stdio.h>
  2. #include<assert.h>
  3. char* my_strstr(char* str1, char* str2)
  4. {
  5. assert(str1 && str2);
  6. char* s1 = NULL;
  7. char* s2 = NULL;
  8. char* cp = str1;
  9. //注意回退
  10. while (*cp)
  11. {
  12. s1 = cp;
  13. s2 = str2;
  14. while ((*s1 == *s2)&&(*s2)!='\0'&&*s1)
  15. {
  16. s1++;
  17. s2++;
  18. }
  19. if (*s2 == '\0')
  20. return cp;
  21. cp++;
  22. }
  23. return NULL;
  24. }
  25. int main()
  26. {
  27. char arr1[20] = "iwillhavetheorder!";
  28. char arr2[20] = "wil";
  29. char* p = my_strstr(arr1, arr2);
  30. if (p != NULL)
  31. puts(p);
  32. else
  33. puts("找不到");
  34. return 0;
  35. }

strtok函数

char * strtok ( char * str, const char * delimiters );

注:

1)strtok函数会根据所提供的字符串分割str1字符串,遇到分割点自动分割,末尾加上'\0'字符,并记录‘\0'位置,
2)下次分割时参数部分应该为(NULL,分割的字符串)

3)使用时除第一次使用str1外,其余使用的都是NULL参数

使用:

  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. char arr1[] = "i will have the order !";
  6. char div[] = " ";
  7. char* ret = NULL;
  8. for (ret = strtok(arr1,div); ret != NULL; ret = strtok(NULL, div))
  9. {
  10. printf("%s\n", ret);
  11. }
  12. return 0;
  13. }

 错误信息报告

strerro函数

注:

1)调用库函数时,如果产生错误就会显示错误的信息

2)需要引入全局变量,只需包含头文件#include<errno.h>

3)函数调用strerror(errno);

使用:

  1. #include<errno.h>
  2. #include<stdio.h>
  3. int main()
  4. {
  5. FILE* fp = fopen("test.text", "r");//打开文件
  6. if(fp==NULL)
  7. printf("%s\n", strerror(errno));//打印错误信息
  8. fclose(fp);//关闭文件
  9. fp=NULL;
  10. return 0;
  11. }

 perror函数

注:

1.错误码转化为错误信息
2.自动打印错误信息

  1. #include<stdio.h>
  2. #include<errno.h>
  3. int main()
  4. {
  5. //打开文件
  6. FILE* fp = fopen("test.t", "r");
  7. if (fp == NULL)
  8. {
  9. perror("fopen");//传入的是字符串
  10. return 1;//结束main函数
  11. }
  12. //写数据
  13. //关闭文件
  14. fclose(fp);
  15. fp = NULL;
  16. return 0;
  17. }

字符操作函数

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。

  1. #include<stdio.h>
  2. #include<ctype.h>
  3. //大小写转换
  4. int main()
  5. {
  6. char ch[] = "asSFAvaasRBeB";
  7. int i = 0;
  8. while (ch[i] != '\0')
  9. {
  10. if (islower(ch[i]))
  11. ch[i] = toupper(ch[i]);
  12. else
  13. if (isupper(ch[i]))
  14. ch[i] = tolower(ch[i]);
  15. i++;
  16. }
  17. printf("%s", ch);
  18. return 0;
  19. }

 

 内存函数

memcpy

void* memcpy(void* dest,const void* src,size_t num);

注:

1)memcpy可处理内存分配不冲突的

使用:

1)调用:

  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
  6. int arr2[10] = { 0 };
  7. memcpy(arr2, arr1, 24);
  8. for (int i = 0; i < 10; i++)
  9. printf("%d ", arr2[i]);
  10. return 0;
  11. }

 2)模拟实现

  1. #include<stdio.h>
  2. #include<assert.h>
  3. void* my_memcpy(void* dest, const void* src, size_t num)
  4. {
  5. assert(dest && src);
  6. void* start = dest;
  7. //强制类型转换为char*
  8. while (num--)
  9. {
  10. *((char*)dest) = *((char*)src);
  11. src = (char*)src + 1;//用后置++的,由于操作符优先级的问题容易错误
  12. dest = (char*)dest + 1;
  13. }
  14. return start;
  15. }
  16. int main()
  17. {
  18. int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
  19. int arr2[10] = { 0 };
  20. my_memcpy(arr2, arr1, 24);
  21. for (int i = 0; i < 10; i++)
  22. printf("%d ", arr2[i]);
  23. return 0;
  24. }

 memmove

void* my_memmove(void* dest, void* src, size_t num)

注:

1)memmove可处理内存冲突的问题

使用:

1)调用

2)模拟实现

关键是要解决内存覆盖的问题

 

 

 注:顺序或逆序只针对src。

其余情况顺逆皆可

当dest<src按顺序排列
 当dest>=src时逆序排列 

  1. #include<stdio.h>
  2. #include<assert.h>
  3. void* my_memmove(void* dest, void* src, size_t num)
  4. {
  5. assert(dest && src);
  6. void* start = dest;
  7. //强转为char*
  8. while (num--)
  9. {
  10. if (dest < src)//顺序替换
  11. {
  12. *(char*)dest = *(char*)src;
  13. dest = (char*)dest + 1;
  14. src = (char*)src + 1;
  15. }
  16. else//逆序替换
  17. *((char*)dest + num) = *((char*)src + num);
  18. }
  19. return start;
  20. }
  21. int main()
  22. {
  23. int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
  24. my_memmove(arr + 3, arr, 16);//1,2,3,1,2,3,4,8,9,0
  25. for (int i = 0; i < 10; i++)
  26. {
  27. printf("%d ", arr[i]);
  28. }
  29. return 0;
  30. }

 memcmp

int my_memcmp(const void* str1,const void* str2, size_t num);

相同返回0
str1>str2 返回1
stsr1<str2 返回-1

  1. int main()
  2. {
  3. int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
  4. int arr2[] = { 1,2,5,4,6,8,6,6,5,6,7 };
  5. int ret = memcmp(arr1, arr2, 20);
  6. printf("%d\n", ret);
  7. return 0;
  8. }

 模拟实现

int my_memcmp(const void* str1,const void* str2, size_t num);

  1. int my_memcmp(const void* str1,const void* str2, size_t num)
  2. {
  3. assert(str1 && str2);
  4. while (num--)
  5. {
  6. if (*(char*)str1 == *(char*)str2)
  7. {
  8. str1 = (char*)str1 + 1;
  9. str2 = (char*)str2 + 1;
  10. }
  11. else
  12. return *(char*)str1 - *(char*)str2;
  13. }
  14. return *(char*)str1 - *(char*)str2;
  15. }
  16. int link(int ret)
  17. {
  18. if (ret > 0)
  19. return 1;
  20. else if (ret == 0)
  21. return 0;
  22. else
  23. return -1;
  24. }
  25. int main()
  26. {
  27. int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
  28. int arr2[] = { 6,3,5,6,8,9,7,1,0 };
  29. int ret = my_memcmp(arr1, arr2, 20);
  30. printf("%d\n",link(ret));
  31. int ret2 = memcmp(arr1, arr2, 20);
  32. printf("%d\n%d", ret,ret2);
  33. return 0;
  34. }

 memset

void* memset(void* ptr,int value,size_t num)
以字节为单位设置内存

  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. int arr[20] = { 0 };
  6. memset(arr, 1, 10);//10个字节设置为1
  7. return 0;
  8. }

没了

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载