本篇字符函数和字符串函数
求字符串长度 strlen
长度不受限制的字符串函数 strcpy strcat strcmp
长度受限制的字符串函数介绍 strncpy strncat strncmp
字符串查找 strstr strtok
错误信息报告 strerror
内存操作函数 memcpy memmove memset memcmp
在我们笔试时,很有可能会让我们自己写这样的库函数,所以我们必须明白这些函数的用法以及如何自己写出这样的函数。
文章目录
- 本篇字符函数和字符串函数
- 1.strlen函数及模拟实现
- 1.1用法
- 1.2模拟实现
- 2.strcpy函数及模拟实现
- 2.1用法
- 2.2模拟实现
- 3.strcat函数及模拟实现
- 3.1用法
- 3.2模拟实现
- 4.strstr函数及模拟实现
- 4.1用法
- 4.2模拟实现
- 5.strcmp函数及模拟实现
- 5.1用法
- 5.2模拟实现
- 6.memcpy函数及模拟实现
- 6.1用法
- 6.2模拟实现
- 7.memmove函数及模拟实现
- 7.1用法
- 7.2模拟实现
- 8. 其他字符函数和字符串函数
- 8.1strncpy
- 8.2strncat
- 8.3strncmp
- 8.4字符分类函数
- 8.5strock
1.strlen函数及模拟实现
1.1用法
字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包 含 ‘\0’ )。
用法举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{const char* str1 = "abcdef";int ret = strlen(str1);printf("%d", ret);return 0;
}
我们可以看到输出就是6,用来计算字符串中 ‘\0’ 前面出现的字符个数。
1.2模拟实现
//方法1,计数器方式
int my_strlen(const char * str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}//方法2,递归函数
int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}//方法3,指针-指针的方式
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
2.strcpy函数及模拟实现
2.1用法
源字符串必须以 ‘\0’ 结束。其会将源字符串中的 ‘\0’ 拷贝到目标空间。
用法举例:
int main()
{char arr1[20] = {0};char arr2[] = "abc";strcpy(arr1, arr2);printf("%s\n", arr1);return 0;
}
2.2模拟实现
char* my_strcpy(char* arr1,char* arr2)
{char* ret = arr1;assert(arr1 != NULL);assert(arr2 != NULL);while (*arr2!='\0'){*arr1 = *arr2;arr1++;arr2++;}return ret;
}
3.strcat函数及模拟实现
3.1用法
追加字符串,把一个字符串放到另一个字符串后面
用法举例:
int main()
{char arr1[30] = "shuaige,and,";char arr2[] = "meinv";printf("%s",strcat(arr1, arr2));return 0;
}
3.2模拟实现
char* my_strcat(char* arr1, char* arr2)
{char* ret = arr1;assert((arr1 && arr2) != NULL);while (*arr1 != '\0'){arr1++;}while (*arr2 != '\0'){*arr1 = *arr2;arr1++;arr2++;}return ret;
}
4.strstr函数及模拟实现
4.1用法
返回arr1中arr2第一次出现的位置,如果arr1中没有arr2,就返回NULL
用法举例:
int main()
{char arr1[] = "abbbcdef";char arr2[] = "bbc";char* ret = strstr(arr1, arr2);if (ret == NULL){printf("找不到哦");}else{printf("%s", ret);}return 0;
}
4.2模拟实现
my_strstr(char* arr1, char* arr2)
{char* record;//记录开始匹配的位置char* s1;//变利arr1指向的字符串char* s2;//变利arr2指向的字符串assert((arr1 && arr2) != NULL);if (*arr2 == '\0')return arr1;record = arr1;while (*record != '\0'){s1 = record;s2 = arr2;while ((*s1 && *s2 && (*s1 == *s2)) != '\0'){s1++;s2++;}if (*s2 == '\0')return record;record++;}return NULL;
}
5.strcmp函数及模拟实现
5.1用法
比较两个字符串的大小(按位比较,也就是一位一位比较)
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
用法举例:
int main()
{char arr1[] = "abc";char arr2[] = "abd";int ret = strcpy(arr1, arr2);if (ret>0)printf("arr1大");else if (ret=0)printf("一样大");else printf("arr2大");return 0;
}
5.2模拟实现
my_strcpy(char* arr1, char* arr2)
{assert((arr1 && arr2) != NULL);while (*arr1 == *arr2){if (*arr1 == '\0')return 0;arr1++;arr2++;}if (*arr1 > *arr2)return 1;elsereturn -1;
}
6.memcpy函数及模拟实现
6.1用法
拷贝数据,数据不重叠,即将一个数组拷贝到另一个不相干的数组。不能实现将一个数组拷贝到这个数组本身。
用法举例:
int main()
{int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };memcpy(arr1, arr2, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
6.2模拟实现
void* my_memcpy(void* arr1, void* arr2, int sz)
{void* ret = arr1;assert((arr1 && arr2) != NULL);while (sz != 0){*(char*) arr1 = *(char*) arr2;arr1 = (char*)arr1 + 1;arr2 = (char*)arr2 + 1;sz--;}return ret;
}
7.memmove函数及模拟实现
7.1用法
拷贝数据,数据重叠时也能做到。即相较于memcpy,可以实现将一个数组拷贝到这个数组本身。
用法举例:
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr + 2, arr, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}
7.2模拟实现
void* my_memmove(void* arr1, const void* arr2, size_t sz)
{assert((arr1 && arr2) != NULL);void* ret = arr1;if (arr1 < arr2){while (sz != 0){*(char*)arr1 = *(char*)arr2;arr1 = (char*)arr1 + 1;arr2 = (char*)arr2 + 1;sz--;}}else{while (sz!=0){sz--;*((char*)arr1 + sz) = *((char*)arr2 + sz);}}return ret;
}
8. 其他字符函数和字符串函数
提示:其他函数没有那么重要,这里只简单说明用法,不再进行模拟实现!
8.1strncpy
相较于strcpy,其可以自定义拷贝多少个字符。
int main()
{char arr1[20] = { 0 };char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);return 0;
}
8.2strncat
相较于strcat,可以自定义在后面拷贝多少个字符。
int main()
{char arr1[20] = "abc\0xxxxxxxxxxxxxx";char arr2[] = "defghi";strncat(arr1, arr2, 5);printf("%s\n", arr1);return 0;
}
8.3strncmp
相较于strcmp,可以指定比较多少个字符。
int main()
{char arr1[] = "abczef";char arr2[] = "abcqw";int ret = strncmp(arr1, arr2, 4);printf("%d\n", ret);return 0;
}
8.4字符分类函数
函数 | 如果他的参数符合下列条件就返回真 |
---|---|
iscntrl | 任何控制字符 |
isdigit | 十进制数字 0~9 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
islower | 小写字母a~z |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF |
isupper | 大写字母A~Z |
isalpha | 字母a-z或A~Z |
isalnum | 字母或者数字,a-z,A-Z,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
8.5strock
char * strtok ( char * str, const char * sep );
①sep参数是个字符串,定义了用作分隔符的字符集合
②第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
③strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
④strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
⑤strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
⑥strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。 如果字符串中不存在更多的标记,则返回 NULL 指针。
int main()
{char arr[] = "dashuaige@yeah.net@hehe.haha";char arr2[] = "192.168.23.101";char buf1[200] = { 0 };//"zpengwei\0yeah.net"strcpy(buf1, arr);char buf2[200] = { 0 };//"192.168.23.101"strcpy(buf2, arr2);char* p = "@.";char* s = NULL;for (s = strtok(buf1, p); s != NULL; s=strtok(NULL, p)){printf("%s\n", s);}char* p2 = ".";for (s = strtok(buf2, p2); s != NULL; s = strtok(NULL, p2)){printf("%s\n", s);}return 0;
}