文章目录
前言
一些常用的字符函数和内存函数
一、字符函数
1.字符串长度
(1)strlen:求字符串长度
size_t strlen(const char *str)
strlen求字符串的长度,就是找到‘\0’就结束。
三种方式模拟实现:
(1)计数器的方法
(2)递归的方法
(3)指针-指针的方法
计数器的方法 :
//1.计数器的方法
int my_strlen1(const char* str) {
int count = 0;//记录字符的个数
assert(str);//断言,字符不为空
while (*str) {
count++;
str++;
}
return count;
}
递归的方法 :
//2.递归的方法
int my_strlen2(const char* str) {
assert(str);
if (*str == '\0') {
return 0;
}
return 1 + my_strlen2(++str);//递归
}
指针-指针的方法
//3.指针-指针的方法
int my_strlen3(const char* str) {
assert(str);
char* start = str;
while (*str) {
str++;
}
return str - start;//指针减指针的结果是字符的个数
}
2.长度不受限制的字符函数
(1)strcpy:拷贝字符串
strcpy : '\0'也会拷到目标空间、目标空间必须足够大。
strcpy模拟实现 :
// strcpy模拟实现
char* my_strcpy(const char* str1, const char* str2) {
assert(str1 && str2);
char* ret = str1;
while (*str1++==*str2++) {
;
}
return ret;
}
(2)strcat: 字符串追加
strcat: 字符串追加,将str2字符串追加在str1后面,str1空间需要足够大。
//strcat 字符串追加 模拟实现
char* my_strcat(char* str1, const char* str2) {
assert(str1 && str2);
char* ret = str1;
while (*str1) {
str1++;
}
while (*str1 == *str2) {
;
}
return ret;
}
int main() {
char arr1[20] = "awe";
char arr2[] = "abcde";
//strcat 字符串追加
printf("strcat(arr1,arr2) = %s\n", strcat(arr1, arr2));
printf("my_strcat(arr1,arr2) = %s\n", my_strcat(arr1, arr2));
return 0;
}
(3)strcmp: 字符串比较
strcmp:比较字符串的大小。
>0:str1>str2;
=0:str1=str2;
<0:str1<str2.
//strcmp模拟实现
int my_strcmp(const char* str1, const char* str2) {
assert(str1 && str2);
while (*str1 == *str2) {
if (*str1 == '\0') { //如果字符串都相等返回0,退出
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;//返回
}
2.长度受限制的字符函数
比起不受限制的字符函数多了一个条件。需要给出操作的大小num。
(1)strncpy、strncat、strncmp
strncpy:char * strncpy ( char * destination, const char * source, size_t num ); 比起strcpy多了一个限制num。
strncat:char * strncat ( char * destination, const char * source, size_t num );
strncmp:int strncmp ( const char * str1, const char * str2, size_t num );
//长度受限制的字符函数
int main() {
//长度受限制的字符函数
//strncpy
char arr1[20] = "abcdef";
char arr2[] = "qwu";
strncpy(arr1, arr2, 3);
printf("%s\n", arr1);
//strncat
printf("%s\n", strncat(arr1, arr2, 2));
//strncmp
int ret = strncmp(arr1, arr2, 2);
if (ret > 0) {
printf(">\n");
printf("%d\n", ret);
}
else if (ret == 0) {
printf("=\n");
printf("%d\n", ret);
}
else {
printf("<\n");
printf("%d\n", ret);
}
return 0;
}
3.字符串查找
(1)strstr
strstr :寻找arr1中有没有arr2,返回第一次出现的地址,如果没有找到返回NULL。
strstr模拟实现 :
//strstr模拟实现
char* my_strstr(const char* str1, const char* str2) {
assert(str1 && str2);
char* s1 = str1;
char* s2 = str2;
char* cur = str1;
while (*cur) {
s1 = cur;
s2 = str2;
while (*s1 == *s2) {
s1++;
s2++;
}
if (*s2 == '\0') {
return cur;
}
cur++;
}
return NULL;
}
(2)strtok
strtok :char* strtok(char* str,const char* stp)
stp是一个字符串,里面定义了分隔符
将str按分隔符截断并返回。
注意:strtok是对str本身进行操作,如果不想改变原有字符串,可以用strcpy先拷贝一份。
int main() {
//strtok
//char* strtok(char* str,const char* stp)
//stp是一个字符串,里面定义了分隔符
//使用
char str[] = "why@qq.com";
char stp[] = "@.";
char buf[20];
strcpy(buf, str);//拷贝一份
//输出方式一
/*printf("%s\n", strtok(buf, stp));
printf("%s\n", strtok(NULL, stp));
printf("%s\n", strtok(NULL, stp));*/
//输出方式二
char* ch = strtok(buf, stp);
for (ch; ch != NULL; ch = strtok(NULL, stp)) {
printf("%s\n", ch);
}
//输出方式三
/*char* tmp;
tmp = strtok(buf, stp);
while (tmp != NULL) {
printf("%s\n", tmp);
tmp = strtok(NULL, stp);
}*/
return 0;
}
4.错误信息报告
strerror
(1)头文件:errno.h
(2)错误码:errno 是一个全局变量
(3)strerror将错误码转换为错误信息
(4)perror()与strerror比较,perror()会将错误信息直接打印
int main() {
//错误信息报告
//将错误码转换为错误信息
//void perror(const char* string)
//perror()会直接打印错误信息
printf("%s\n", strerror(1));
printf("%s\n", strerror(2));
printf("%s\n", strerror(3));
//int* p = (int*)malloc(40);
int* p = (int*)malloc(INT_MAX);
if (p == NULL) {
printf("%s\n", strerror(errno));
perror("malloc");
}
return 0;
}
5.字符操作
(1)头文件ctype.h
函数 | 条件 |
---|---|
iscntrl | 任何控制字符 |
isspace | 空白字符 ’ ‘,’\f’换页,’\n’,’\r’回车,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数0-9 |
isxdigit | 十六进制数 |
islower | 小写字母 |
isupper | 大写字母 |
isalpha | a-z/A-Z |
isalnum | a-z/A-Z/0-9 |
ispunct | 变点符号,任何不属于数字或字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
tolower() | 转换为小写字母 |
toupper() | 转换为大写字母 |
int main() {
//字符操作 ctype.h
// iscntrl 任何控制字符
//isspace 空白字符 ' ','\f'换页,'\n','\r'回车,制表符'\t'或者垂直制表符'\v'
//isdigit 十进制数0-9
printf("%d\n", isdigit('5'));
//isxdigit 十六进制数
printf("%d\n", isdigit('f'));
char ch1 = 'A';
char ch2 = 'a';
//islower 小写字母
printf("%d\n", islower(ch1));
//isupper 大写字母
printf("%d\n", isupper(ch1));
//isalpha a-z/A-Z
printf("%d\n", isalpha(ch1));
//isalnum a-z/A-Z/0-9
printf("%d\n", isalnum(ch1));
//ispunct 变点符号,任何不属于数字或字母的图形字符(可打印)
//isgraph 任何图形字符
//isprint 任何可打印字符,包括图形字符和空白字符
//字符转换 tolower() toupper()
printf("%c\n", tolower(ch1));
printf("%c\n", toupper(ch2));
return 0;
}
二、内存函数
1.memcpy
memcpy :将非字符的数组进行拷贝,一个字节一个字节进行拷贝
(自己拷贝到自己本身存在缺陷)
memcpy模拟实现 :
//memcpy模拟实现
//存在缺陷 vs编译器忽略了
void* my_memcpy(void* des, const void* src, size_t count) {
assert(des && src);
void* ret = des;
while (count--) {
*((char*)des) = *((char*)src);
des = (char*)des + 1;
src = (char*)src + 1;
}
return ret;
}
2.memove
memove:可以实现重叠内存拷贝,解决memcpy存在的缺陷。
例:
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
//memmove(arr1, arr1+2, 20);
//memmove(arr1+2, arr1, 20);
memove模拟实现 :
//memmove模拟实现
void* my_memmove(void* des, const void* src, size_t count) {
assert(des && src);
char* ret = des;
//前-后
if (*((char*)des) < *((char*)src)) {
while (count--) {
*((char*)des) = *((char*)src);
des = (char*)des + 1;
src = (char*)src + 1;
}
}
else {
//后-前
while (count--) {
*((char*)des + count) = *((char*)src + count);
}
}
return ret;
}
3.memcmp
memcmp:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较从ptr1和ptr2指针开始的num个字节。
该函数是按字节比较的。
(1)返回值 < 0,则表示 str1 小于 str2。
(2)返回值 > 0,则表示 str2 小于 str1。
(3)返回值 = 0,则表示 str1 等于 str2。
注意:该函数是按字节比较的。
4.memset
memset:void * memset ( void * ptr, int value, size_t num );
(1)内存设置,以字节为单位初始化内存。
(2)常用于内存空间初始化。
(3)可以方便的清空一个结构类型的变量或数组。
int main() {
//memcmp
int arr1[] = { 1,2,3,4,5,6 };
int arr2[] = { 1,2,3,4 };
int ret = memcmp(arr1, arr2, 16);
printf("%d\n", ret);
//memset 内存设置 以字节为单位初始化内存
int arr[] = { 1,2,3,4,5 };
memset(arr, 6, 16);
for (int i = 0; i < (sizeof(arr) / sizeof(int)); i++) {
printf("%p ", arr[i]);
}
return 0;
}