-
Strlen
size_t strlen ( const char * str );
- 返回类型是size_t(无符号整型)
-
字符串已经 '\0' 作为结束标志, strlen 函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' ) 。
-
没有'\0'做为结束标志的话会一直在内存中向后找,直到找到'\0'。
模拟实现
-
计数器
size_t my_strlen(const char* str) { int count = 0; while (*str) { count++; str++; } return count; }
-
递归
size_t my_strlen(const char* str) { if (*str!=0 ) { return 1 + my_strlen(str + 1); } else { return 0; } }
-
指针➖指针
size_t my_strlen(const char* str) { char* str1=str; while (*str) { str++; } size_t ret= str-str1; return ret; }
-
Strcpy(拷贝)
char* strcpy ( char * destination , const char * source );
- 拷贝结束的标志是“\0”
- 还要把“\0”拷贝过去
- 目标空间必须足够大
- 目标空间必须能够更改,放入
-
Strcat(追加)
char * strcat ( char * destination , const char * source );
- 追加位置的字符串一定要有“\0”作为起点
- 源字符串也要有“\0”,作为拷贝的完成的终点
- 追加位置的空间必须足够大
模拟实现
- 找到目标空间中的“\0”
- 拷贝字符串
- 注意自己不能改变自己
char* my_strcat(char* destination, const char* source)
{
assert(destination, source);
char* s1 = destination;
char* s2 = source;
while (*s1)
{
s1++;
}
while (*s2)
{
*s1 = *s2;
s1++;
s2++;
}
*s1 = *s2;
return destination;
}
int main()
{
char a[20] = "hello ";
char b[] = "world";
my_strcat(a, b);
printf("%s ", a);
return 0;
}
-
strcmp
int strcmp ( const char * str1 , const char * str2 );
用==的时候比较的是字符串首字符的地址,用strcmp比较的是字符串的内容
int my_strcmp(const char* str1, const char* str2)
{
while (*str1 == *str2 &&*str1 &&*str2)
{
str1++;
str2++;
}
if (*str1 > *str2)
{
return 1;
}
else if (*str1 < *str2)
{
return -1;
}
else
{
return 0;
}
}
int main()
{
char a[20] = "hello ";
char b[] = "hello ";
printf("%d ", my_strcmp(a,b));
return 0;
}
模拟实现
这三个字符串函数不受长度限制
-
Strncmp.strncat.strncpy长度受限的函数,可以指定比较/追加/拷贝的字符数
-
strncpy
char * strncpy ( char * destination , const char * source , size_t num );
- 拷贝不够,拿“/0”来凑
-
strncat
char * strncat ( char * destination , const char * source , size_t num );
- 追加指定字符个数后会补上一个“\0”
- 不会像拷贝那样去多凑“/0”
-
Strstr
char * strstr ( const char * str1 , const char * str2 );
- 在一个字符串中找另外一个字符串,多次出现的话返回第一次出现的地址
模拟实现
- 两个指针(s1.s2)分别维护两个字符串,避免字符串首地址指针发生改变
- 一个指针(P)用于记住开始匹配的地址
- 传入的两个指针不能用于修改字符串,所以要加Const
- 当两个指针指向的字符不相等时,长串往后走,找到第一个与子串首字符相等地址
- 找到后,s1,s2分别向后走继续去匹配
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
char* s1 = str1;
char* s2 = str2;
char* pt = str1;
while (*pt)
{
s1 = pt;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return pt;
}
pt++;
}
return NULL;
}
int main()
{
char a[20] = "hello ";
char b[] = "ell";
//my_strcat(a, b);
printf("%s ", my_strstr(a,b));
return 0;
}
-
strchr
char * strchr ( const char * str1 , char c );
- 在一个字符串中找另外一个字符第一次出现的位置
-
strtok
char * strtok ( char * str , const char * sep );
- 提取被分割符分割的字符
- 参数分别为:需要提取字符串,有分隔符组成的字符串
- 会把字符串里面的分隔符的位置直接改为“\0”
- 由于会改变字符串,所以一般不直接穿传入原字符串,会传入临时拷贝进行更改
- for循环使用strtokstrtok
-
Strerror
char * strerror ( int errnum );
- 把错误码对应的错误信息返回出来
- C语言的库函数调用失败的时候会将错误码存放在一个叫errno(要引用errno.h的头文件)的变量中,当我们想知道发生了什么的错位信息,就可以将strror (errno)将错误信息打印出来,库函数公用errno,会被替换,所以要及时检查
- 进阶版,perror,可以同时找出错误信息并打印,strror只能找,需要程序员自己打印
- 一系列字符分类函数
iscntrl
任何控制字符
isspace
空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit
十进制数字 0~9
isxdigit
十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower
小写字母a~z
isupper
大写字母A~Z
isalpha
字母a~z或A~Z
isalnum
字母或者数字,a~z,A~Z,0~9
ispunct
标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph
任何图形字符
isprint
任何可打印字符,包括图形字符和空白字符