strlen
1.2长度不受限制的字符串函数strcpy
strcmp
strcat
1.3长度受限制的字符串函数strncpy
strncmp
strncat
1.4字符串查找strstr
strtok
1.5 错误信息报告strerror
1.6字符 *** 作
1.7内存 *** 作函数memcpy
memmove
2 函数的使用 2.1.1 strlen求字符串的长度
size_t strlen ( const char * str )
字符串是以'/0'作为结束标志,但'/0'不记作字符串的长度
strlen返回的是无符号的整形,因为长度不可能为负数
#include
#include //strlen函数的使用需要引用的头文件
int main()
{
char arr[] = "abcdefg";
int ret = strlen(arr);// strlen要返回一个整形,所以需要一个整形变量来接收
printf("字符串的长度为%d", ret);
return 0;
}
2.1.2 模拟实现
#include
size_t my_strlen(const char* pc)//用cosnt修饰,是因为在这里不需要对地址进行改动
{
int ret = 0;
while (*pc)// 当pc指向的内容为'/0'的时候就停止
{
ret++;
pc++;
}
return ret;
}
int main()
{
char arr[] = "abcdefg";
int ret = my_strlen(arr);
printf("字符串的长度是%d", ret);
return 0;
}
2.2.1 strcpy
拷贝字符串
char * strcpy ( char * destination, const char * source )
strcpy函数返回一个指针变量,所以要用指针接收
cosnt 修饰*source是因为源头函数不需要改变
#include
#include
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdefg";
char* pc = strcpy(arr1, arr2);//返回指针用指针接收
printf("被拷贝后的arr1-> %s\n", arr1);
return 0;
}
2.2.2 模拟实现
#include
char* my_strcpy(char* dest, const char* sou)
{
char* ret = dest;//保存原地址
while (*sou)
{
*ret = *sou;//拷贝后地址各往后移动一个单位
ret++;
sou++;
}
return dest;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdefg";
char* ret = my_strcpy(arr1, arr2);
printf("被拷贝后的arr1-> %s\n", arr1);
return 0;
}
2.3.1 strcmp
int strcmp ( const char * str1, const char * str2 )
比较字符串的大小,并且在不同情况返回不同值
注:大小的比较是一个字符和一个字符的比较
#include
#include
int main()
{
char arr1[] = "abcdefg";
char arr2[] = "abcdeff";
int ret = strcmp(arr1, arr2);
if (ret > 0)
{
printf("arr1大于arr2");
}
else if (ret < 0)
{
printf("arr1小于arr2");
}
else
{
printf("arr1等于arr2");
}
return 0;
}
2.3.2 模拟实现
#include
int my_strcmp(const char* str1, const char* str2)
{
while (*str1)
{
if (*str1 > *str2)
{
return 1;
}
else if (*str1 < *str2)
{
return -1;
}
str1++;
str2++;
}
if ((*str1 == '< 0)
{
printf("arr1小于arr2");
}
else
{
printf("arr1等于arr2");
}
return 0;
}
') && (*str2 != '
'))
return -1;//当arr1的长度小于arr2长度时
return 0;//跳出循环时,代表两组字符串包含的内容相同
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "abcdeff";
int ret = my_strcmp(arr1, arr2);
if (ret > 0)
{
printf("arr1大于arr2");
}
else if (ret
2.4.1 strcat
char * strcat ( char * dest, const char * sou)
将sou字符串追加到dest的结尾
#include
#include
int main()
{
char arr1[20] = "abcd";
char arr2[] = "efgh";
char* ret = strcat(arr1, arr2);
printf("添加后的arr1-> %s\n", ret);
return 0;
}
2.4.2 模拟实现
#include
char* my_strcat(char* dest, const char* sou)
{
char* pc = dest;//保存dest的地址
//找到arr1字符串结束的地址
while (*pc)
{
pc++;
}
//当到arr2字符串'/0'位置时结束
while (*sou)
{
*pc = *sou;
pc++;
sou++;
}
return dest;
}
int main()
{
char arr1[20] = "abcd";
char arr2[] = "efgh";
char* ret = my_strcat(arr1, arr2);
printf("添加后的arr1-> %s\n", ret);
return 0;
}
2.5.1 strncpy
char * strncpy ( char * destination, const char * source, size_t num )
在strcpy的基础上增加了可选择拷贝字符串长度的功能
num为选择拷贝字符串长度的参数,用无符号整形修饰
#include
#include
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdefg";
char* ret = strncpy(arr1, arr2, 4);//4为拷贝几个字符的参数
printf("拷贝4个字节后的arr1-> %s\n", ret);
return 0;
}
2.5.2 模拟实现
#include
char* my_strncpy(char* dest, const char* sou, size_t num)
{
char* ret = dest;//保留dest的地址
while (num--)//循环执行的次数
{
*ret = *sou;
ret++;
sou++;
}
return dest;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdefg";
char* ret = my_strncpy(arr1, arr2, 4);
printf("拷贝4个字符后的arr1-> %s\n", ret);
return 0;
}
2.6.1 strncmp
int strncmp ( const char * str1, const char * str2, size_t num )
在strcmp的基础上增加可选择比较字符的个数
#include < 0)
{
printf("前4个字符 arr1 比 arr2 小\n");
}
else
{
printf("前4个字符 arr1 和 arr2 相等\n");
}
return 0;
}
#include
int main()
{
char arr1[] = "abcdefg";
char arr2[] = "abcfeff";
int ret = strncmp(arr1, arr2, 4);
if (ret > 0)
{
printf("前4个字符 arr1 比 arr2 大\n");
}
else if (ret
2.6.2 模拟实现
< *str2)
{
return -1;
}
else// 当相等时往后移动一个字符
{
str1++;
str2++;
}
}
return 0;//退出循环时,表示选择长度的字符串相等
}
int main()
{
char arr1[] = "abcdefg";
char arr2[] = "abcfeff";
int ret = my_strncmp(arr1, arr2, 4);
if (ret >#include < 0)
{
printf("前4个字符 arr1 比 arr2 小\n");
}
else
{
printf("前4个字符 arr1 和 arr2 相等\n");
}
return 0;
}
int my_strncmp(char* str1, char* str2, size_t num)
{
while (num--)
{
if (*str1 > *str2)
{
return 1;
}
else if (*str1
0)
{
printf("前4个字符 arr1 比 arr2 大\n");
}
else if (ret
2.7.1 strncat
char * strncat ( char * destination, const char * source, size_t num )
在strcat的基础上可以选择在destination出现第一个'\0'位置后加上source字符的个数
#include
#include
int main()
{
char arr1[20] = "abcdef\0qqqqqq";//判断是否在第一个出现'\0'位置添加字符
char arr2[] = "xyz";
char* ret = strncat(arr1, arr2, 2);
printf("%s\n", ret);
return 0;
}
2.7.2 模拟实现
< num; i++)
{
*ret = *sou;
ret++;
sou++;
}
//判断添加的字符串长度是否大于原字符串长度
//如果小于需添加'
'
if (num < length)
{
int len = sizeof(dest);//求添加字符后目标字符串的长度
dest[len] = ''; } return dest; } int main() { char arr1[20] = "abcdef
qqqqqq";//判断是否在第一个出现''位置添加字符 char arr2[] = "xyz"; char* ret = my_strncat(arr1, arr2, 2); printf("%s\n", ret); return 0; } #include
char* my_strncat(char* dest, const char* sou, int num) { char* ret = dest; int length = sizeof(sou); while (*ret) { ret++; } int i = 0; for (i = 0; i
2.8.1 strstr
char * strstr ( char * str1, const char * str2 )
strstr实现str2是否在str1中存在,如果存在,返回从存在字符开始后面的字符串,即返回存在字符开始的地址,如果不存在返回Null。
#include
#include
int main()
{
char arr1[] = "abcdefabcdef";
char arr2[] = "cd";
char* ret = strstr(arr1, arr2);
printf("%s", ret);
return 0;
}
2.8.2 模拟实现
#include
char* my_strstr(const char* dest, const char* sou) { if (*sou == '\0')//如果源头字符串为空字符串,表明所有所有字符串都能与其对应 return dest; char* pc = dest; while (*pc) { char* s1 = pc; char* s2 = sou; while ((*s1 == *s2) && *s1 != '\0' && *s2 != '\0') { s1++; s2++; } if (*s2 == '\0')//说明sou出现在了dest中 return pc; pc++; } if (*pc == '\0') return NULL;//退出循环表示在dest中未找到sou } int main() { char arr1[] = "abcdefabcdef"; char arr2[] = "cde"; char* ret = my_strstr(arr1, arr2); if (ret == NULL) printf("不存在"); else printf("%s", ret); return 0; }2.9.1 strtok
char * strtok ( char * str, const char * delimiters )
delimiters参数是字符串,内容是用作分隔符的字符的集合
strtok函数会找到str中的下一个标记,并将其用'\0'结尾,返回一个指向这个标记的指针(注意:strtok函数会改变str字符串的内容,所以在使用strtok函数切分的字符串一般用的是临时拷贝的内容并可以修改)
strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置
strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
如果字符串中不存在更多的标记,则返回NULL指针。 上述为strtok函数的使用功能和注意事项
简单使用strtok
#include #include
int main() { char arr1[] = "abcd!efgh@ijkl"; const char arr2[] = "!@"; char buf[100] = { 0 };//拷贝arr1 strcpy(buf, arr1); char* ret = strtok(buf, arr2); printf("%s\n", ret); //由于第一次使用strtok时将分隔符赋值为'\0' //起始位置就变为了空值 //需要分割几次就调用几次strtok ret = strtok(NULL, arr2); printf("%s\n", ret); ret = strtok(NULL, arr2); printf("%s\n", ret); return 0; }
优化代码
#include #include
int main() { char arr1[] = "abcd!efgh@ijkl"; char arr2[] = "!@"; char buf[100] = { 0 }; strcpy(buf, arr1); char* str = NULL; //把起始位置赋值成strtok使用后的地址 //判断条件是当strtok返回NULL值时结束 for (str = strtok(buf, arr2); str != NULL; str = strtok(NULL, arr2)) { printf("%s\n", str); } return 0; }
2.10.1 strerror
char * strerror ( int errnum )
errnum 是C语言中提供的一个全局变量,表示错误信息所使用的数字
strerror函数实现将errnum转换位我们能读取错误信息的字段
#include #include
int main() { printf("%s\n", strerror(1)); printf("%s\n", strerror(2)); printf("%s\n", strerror(3)); printf("%s\n", strerror(4)); return 0; }函 | 符合条件返回真值 | |||||
---|---|---|---|---|---|---|
iscntrl | 检查是否为控制字符 | isspace | 空白字符:' ', ' \f ','\n','\r','\t', '\v' | isdigit | 十进制 0~9 | |
isxdigit | ||||||
islower | 小写字母 a~z | isupper | 大写字母 A~Z | |||
isalpha | ||||||
isalnum | 字母或数字 0~9 a~z A~Z | ispunct | 标点符号 |
需要引 头文件
都返回整形
#include
int main() { char i = 'a'; printf("%d\n", isupper(i)); printf("%d\n", islower(i)); return 0; }非零为真
内存 *** 作函数 2.12.1 memcpyvoid * memcpy ( void * dest, const void * sou, size_t num )
比strcpy功能更强, 能够进行各种类型的拷贝
同时可选择需要拷贝的数量
其中 参数用void* 修饰是为可以接收任何类型的数据
num 的单位是字节, 在使用时,需要清楚需要几个字节
#include #include
int main() { int arr1[10] = { 0 }; int arr2[] = { 1,2,3,4,5,6,7,8,9,10 }; memcpy(arr1, arr2, 28);//28 代表sizeof(int) * 7 return 0; }
监视
2.12.2 模拟实现
#include
void* my_memcpy(void* dest, const void* sou, size_t num) { while (num--) { //因为num是以一个字节为单位 //并且dest和sou都是void*的类型 //需在运用时进行强制类型转换 //也必须转换为同样以一个字节为单位的 char* 类型 *(char*)dest = *(char*)sou; dest = (char*)dest + 1; sou = (char*)sou + 1; } } int main() { int arr1[10] = { 0 }; int arr2[] = { 1,2,3,4,5,6,7,8,9,10 }; my_memcpy(arr1, arr2, 28);//28 代表sizeof(int) * 7 return 0; }
2.13.1 memmove
void * memmove ( void * destination, const void * source, size_t num )
memmove 和 memcpy 函数功能相同, 但解决了对自身函数拷贝时,如有重叠部分时逻辑的错误。但现在的编译已经能够自身解决这种问题,即使这样,从严谨的态度上,依旧使用memmove
#include
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 28);//28 代表sizeof(int) * 7
return 0;
}< (char*)sou)
{
while (num--)
{
*(char*)dest = *(char*)sou;
dest = (char*)dest + 1;
sou = (char*)sou + 1;
}
}
else
{
while (num--)
{
*((char*)ret + num) = *((char*)sou + num);
}
}
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1, arr1 + 2, 28);//28 代表sizeof(int) * 7
return 0;
}
2.13.2 模拟实现
#include
void* my_memmove(void* dest, const void* sou, size_t num) { char* ret = dest; if ((char*)dest2.14. 总结
以上就是字符串函数和部分内存 *** 作函数,在模拟实现这些函数, 以上模拟的代码还有很多地方可以进行优化,随着我们代码能力的提高,我们写的代码肯定会越来越好。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)