目录
一. strlen函数
1.strlen的定义
size_t strlen( const char* str );
->1. strlen函数可以计算出字符串的实际长度(遇到结束符\0结束,不包含\0)
->2. 返回值size_t 就是无符号整型(int unsigned)
typedef 新旧命名,用法:typedef unsigned int size_t 即:unsigned int被size_t替换
->3. const char* str 需要计算字符串的首地址,const保护传过来的数据不被篡改
2.strlen的使用
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "abcdef";
int len = strlen(arr);
printf("%d", len);
retunrn 0;
}
得出的len的值为:6(数组的长度)
使用strlen注意事项:
->1.字符串的地址必须以终止符'\0'结束
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = {'a','b','c'};
int len = strlen(arr);
retunrn 0;
}
因为strlen测量字符串是到'\0'结束,由于字符串中没有结束符'\0',strlen找不到结束计算的标志,就会一直向后寻找结束符'\0',直到找到'\0'为止,在此期间的所以我们不知道strlen函数遇到了多少字符,所以arr数组的长度是不可预知的,即arr的数组的长度是一个随机值
3.strlen的模拟实现
assert函数的作用:判断该地址是不是有效地址
模拟实现strlen有三种方法:
->1. 计数器
#include <stdio.h>
#include <assert.h>
int My_strlen(const char* str)
{
assert(str);
int count = 0;
while(*str++)
{
count++;
}
return count;
}
->2. 指针 - 指针
#include <stdio.h>
#include <assert.h>
int My_strlen(const char* str)
{
assert(str);
char* det = str;
while(*str++)
{
;
}
return str - det;
}
->3. 递归
#include <stdio.h>
#include <assert.h>
int My_strlen(const char* str)
{
assert(str);
if(*str == '\0')
return 0;
else
return 1 + My_strlen(str + 1);
}
二. strcpy函数
1.strcpy的定义
char *strcpy( char *Destination, const char *Source );
->1. 拷贝字符串(Source)放入目标空间(Destination)中
->2. char *Destination --- 目标空间的首地址
->3. const char *Source --- 源字符串的首地址,加上const保护字符串再操作过程中不被篡改
->4. 返回值为:操作完成后,返回终点目地的首地址
2.strcpy的使用
#include <stdio.h>
#include <string.h>
int main()
{
char name[20] = {0};
strcpy(name, "abcdef");
printf("%s", name);
return 0;
}
运行结果:
使用strcpy注意事项:
例1:
#include <stdio.h>
#include <string.h>
int main()
{
char name[20] = {0};
strcpy(name, "zhangsan");
printf("%s", name);
return 0;
}
运行结果:
strcpy函数拷贝到'\0'结束,它会将‘\0’之前的字符拷贝到name中包括'\0',用strcpy时,原数据需要'\0',不然没法停止
例2:
#include <stdio.h>
#include <string.h>
int main()
{
char name[3] = {0};
strcpy(name, "zhang");
printf("%s", name);
return 0;
}
运行结果:
目标空间(name数组)太小装不下源字符串,程序会崩溃,但是内容还是会拷贝过去
例3:
#incldue <stdio.h>
#include <string.h>
int main()
{
char* p = "abcdef";
char str[] = "bit";
strcpy(p, arr);
return 0;
}
运行结果:
目标空间必须是可变的,不然程序就会崩溃,存放常量字符串的字符指针变量p的空间是不可变的
例4:
#include <stdio.h>
#include <string.h>
int main()
{
char name[20] = "##################";
strcpy(name, "zhangsan");
printf("%s", name);
return 0;
}
运行结果:
可以看到strcpy函数拷贝字符串时源字符串中的'\0'也会被拷贝进目标空间
总结:
->1. 源字符串必须以‘\0’结束
->2. 会将源字符串中的'\0'拷贝目标空间
->3. 目标空间必须足够大,以确保能存放源字符串
->4. 目标空间必须可变
3.strcpy的模拟实现
#include <stdio.h>
#include <string.h>
char* My_strcpy(char* str1, const char* str2)
{
assert(str1&&str2);
char* det = str1;
while(*str++ = *str2++)
{
; //因为只有一条语句所以外面这对大括号可以省略
}
return det;
}
三. strcat函数
1.strcat的定义
char* strcat(char* Destination, const char* Source);
->1. 将字符串(Source)连接到目标空间(Destination)上
->2. char *Destination --- 目标空间的首地址
->3. const char *Source --- 源字符串的首地址,加上const保护字符串再操作过程中不被篡改
->4. 返回值为:操作完成后,返回终点目地的首地址
2.strcat的使用
#include <stdio.h>
#include <string.h>
int main()
{
char str[20] = "hello ";
strcat(str, "world");
printf("%s", str);
return 0;
}
运行结果:
strcat使用注意事项:
例1:
#include <stdio.h>
#include <string.h>
int main()
{
char str[20] = "hel\0lo ";
strcat(str, "world");
printf("%s", str);
return 0;
}
字符在使用strcat连接时,原字符串会连接在目标空间第一个出现'\0'的地方覆盖掉'\0'之后向后连接,原字符中必须的有终止符'\0',不然strcat函数会一直向后连接直到遇到'\0'
总结:
->1.目标空间需要足够大,能装下连接之后的新字符串
->2.与strcpy一样目标空间必须是可变的
->3.源字符串中的有'\0'
3.strcat的模拟实现
#include <assert.h>
#include <stdio.h>
char* My_strcat(char* det, const char* src)
{
assert(det&&src);
char* start = det;
while(*det)
{
det++;
}
while(*det++ = *src++)
{
;
}
return start;
}
注意:
不可自己跟自己追加:My_strcat(str, str)
会将'\0'覆盖掉,没有'\0'程序会陷入死循环
例:
四. strcmp函数
1.strcmp的定义
int strcmp( const char *string1, const char *string2 );
->1. 比较字符串的大小
->2. 放入需要比较大小的两个字符串的首地址到strcmp函数中
->3. 如str1大于str2就放回正整数,相等返回零,反之返回负整数
2.strcmp的使用
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "zhangsan";
char str2[20] = "zhangsanfeng";
int ret = strcmp(str1, str2);
if(ret > 0)
printf("str1 > str2");
else if(ret == 0)
printf("str1 == str2");
else
printf("str1 < str2");
return 0;
}
3.strcmp的模拟实现
#include <stdio.h>
#include <assert.h>
int My_strcmp(const char* str1, const char* str2)
{
while(*str1 == *str2)
{
if(*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
以上是长度不受限制的字符串函数
下面介绍长度受限制的字符串函数(于上面的字符串函数而言这种字符串函数的相对比较安全,且作用都是一样)
五. strncpy函数
1.strncpy的定义
char *strncpy( char *Destination, const char *Source, size_t count );
相比较strcpy而言功能一样,只是多了一个参数:size_t count 来控制拷贝个数
2.strncpy的使用
将str2的前五个字符复制到str1上
#include <stdio.h>
#incldue <string.h>
int main()
{
char str1[20] = "abcdefg";
char str2[20] = "holle world";
strncpy(str1, str2, 5);
printf("%s", str1);
return 0;
}
运行结果:
例1:
拷贝的个数如果够就拷贝过去,不够就补'\0'
#include <stdio.h>
#incldue <string.h>
int main()
{
char str1[20] = "abcdefg";
char str2[20] = "mfn";
strncpy(str1, str2, 5);
printf("%s", str1);
return 0;
}
运行结果:
3.strncpy的模拟实现
#include <stdio.h>
#include <assert.h>
char* My_strncpy(char* det, const char* src, int count)
{
assert(det && src);
char* start = det;
while ((*det++ = *src++) && count--)
{
;
}
if (count)
{
while (count--)
{
*det++ = '\0';
}
}
return start;
}
int main()
{
char str1[20] = "abcdefg";
const char str2[20] = "mfn";
printf("%s", My_strncpy(str1, str2, 5));
return 0;
}
六. strncat函数
1.strncat的定义
char *strncat( char *Destination, const char *Source, size_t count );
相比较strcat而言功能一致,多了一个参数:size_t count 来控制连接个数
2.strncat的使用
将str2的三个字符连接到str1后面
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "hello\0xxx";
char str2[20] = "wor";
strncat(str1, str2, 3);
printf("%s", str1);
return 0;
}
运行结果:
在结尾会补'\0'作结束处理
将3改为6结果还是一样不会多补'\0'
3.strncat的模拟实现
#include <stdio.h>
#include <assert.h>
char* My_strncat(char* det, const char* src, int count)
{
assert(det && src);
char* start = det;
while (*det)
{
det++;
}
while ((*det++ = *src++) && count--)
{
;
}
if (!count)
{
*++det = '\0';
}
return start;
}
int main()
{
char str1[20] = "hello\0xxx";
char str2[20] = "wor";
printf("%s", My_strncat(str1, str2, 6));
return 0;
}
七. strncmp函数
1.strncmp的定义
int strncmp( const char *string1, const char *string2, size_t count );
相比较strcmp而言功能相同,多了一个参数:size_t count 来控制比较个数
2.strncmp的使用
比较str1和str2的前三个字符的大小
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcdef";
char str2[] = "abc";
int ret = strncmp(str1, str2, 3);
if(ret > 0)
printf("str1 > str2");
else if(ret == 0)
printf("str1 == str2");
else
printf("str1 < str2");
return 0;
}
运行结果:
3.strncmp的模拟实现
#include <stdio.h>
#include <assert.h>
int My_strncmp(const char* str1, const char* str2, int count)
{
assert(str1&&str2);
while ((*str1 == *str2) && --count)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
int main()
{
char str1[] = "abcdef";
char str2[] = "abc";
int ret = My_strncmp(str1, str2, 3);
if (ret > 0)
printf("str1 > str2");
else if (ret == 0)
printf("str1 == str2");
else
printf("str1 < str2");
return 0;
}
建议使用带n的版本,比较严谨一些