一、求字符串长度
①函数:strlen()
size_t strlen (const char* str)
②模拟实现:
<1>计数器
#include<stdio.h>
int my_strlen(char* pch)
{
int count = 0;
while (*pch)
{
count++;
pch++;
}
return count;
}
int main()
{
char ch[] = "Hello World!";
int ret=my_strlen(ch);
printf("%d\n",ret);
return 0;
}
<2>递归
#include<stdio.h>
int my_strlen(char* pch)
{
if (*pch == '\0')
return 0;
else
return 1 + my_strlen(pch+1);
}
int main()
{
char ch[] = "Hello World!";
int ret=my_strlen(ch);
printf("%d\n",ret);
return 0;
}
<3>指针-指针
#include<stdio.h>
int my_strlen(char* pch)
{
char* pch1 = pch;
while (*pch++);
return pch - pch1-1;
}
int main()
{
char ch[] = "Hello World!";
int ret=my_strlen(ch);
printf("%d\n",ret);
return 0;
}
③字符串以'\0'作为结束标志,strlen返回的是‘\0’前面的字符的个数(不包含\0)。
④参数指向的字符串必须以‘\0‘结束。
⑤strlen函数的返回值类型为size_t,为无符号整数。
注意:如果是两个返回值(无符号整数)相减,得到的结果也是无符号整数。
二、长度不受限制的字符串函数
1、字符串拷贝
①函数:strcpy
char* strcpy(char* destination,const char* source)
②模拟实现
#include<assert.h>
void my_strcpy(char* des,const char*sour)
{
assert(des&&sour);
while (*des++ = *sour++);
}
int main()
{
char ch1[] = "Hello World!";
char ch2[20];
my_strcpy(ch2, ch1);
printf("%s\n", ch2);
return 0;
}
③源字符串必须以’\0’结束。
④会将源字符串中的‘\n’拷贝到目标空间。
⑤目标空间必须足够大,以确保能存放源字符串。
⑥目标空间必须可变(可以使源字符串覆盖原本的字符串)。
2、字符串加长
①函数strcat
char* strcat(char* destination,const char*source)
②模拟实现
#include<stdio.h>
#include<assert.h>
void my_strcat(char* des, const char* sour)
{
assert(des&&sour);
while (*des)
des++;
while (*des++ = *sour++);
}
int main()
{
char ch1[20] = "Hello ";
char ch2[] = "World!";
my_strcat(ch1,ch2);
printf("%s\n",ch1);
return 0;
}
③目标空间必须足够大,以确保加进去源字符串不会造成空间不足。
④目标空间必须可修改。
3、比较两个字符串
①函数strcmp
int strcmp(const char* str1,const char* str2)
②模拟实现
#include<stdio.h>
int my_strcmp(const char* str1, const char* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char ch1[] = "abcdefef";
char ch2[] = "abcdefe";
int ret = my_strcmp(ch1, ch2);
if (ret > 0)
printf("第一个字符串大\n");
else if (ret < 0)
printf("第二个字符串大\n");
else
printf("两个字符串相等\n");
return 0;
}
③标准规定 :
第一个字符串大于第二个字符串,则返回大于0的数字。
第一个字符串等于第二个字符串,则返回0。
第一个字符串小于第二个字符串,则返回小于0的数字。
④两个字符串相比较,比较的是两个字符串对应字符的ASCⅡ值的大小。
三、长度受限制的字符串函数
1、拷贝字符串
①函数:strncpy
char* strncpy(char* destination,const char* source,size_t num)
②模拟实现
#include<stdio.h>
typedef unsigned int size_t;
void my_strcpy(char* des, char*sour,size_t num)
{
while (num--)
{
*des++ = *sour++;
if (*(des - 1) == '\0')
break;
}
if (*(des-1)!='\0')
*des = '\0';
}
int main()
{
char ch1[] = "Hello World!";
char ch2[20] = "##############";
my_strcpy(ch2,ch1,3);
printf("%s\n",ch2);
return 0;
}
③从源字符串中拷贝num个字符到目标空间。
④如果源字符串的长度小于num,则拷贝完字符串之后,后面追加‘\0',直到num个。
2、字符串加长
①函数strncat
char* strncat(char* destination,const char* source,size_t num)
②模拟实现
#include<stdio.h>
#include<assert.h>
typedef unsigned int size_t;
void my_strcat(char* des, const char* sour,size_t num)
{
assert(des&&sour);
while (*des)
des++;
while (num--)
{
*des++ = *sour++;
if (*(des - 1) == '\0')
break;
}
if(*(des-1)!='\0')
*des='\0';
}
int main()
{
char ch1[20] = "Hello ";
char ch2[] = "World!";
my_strcat(ch1,ch2,8);
printf("%s\n",ch1);
return 0;
}
③如果num小于源字符串字符的个数,那么拷贝完num个字符之后直接在后面再加一个’\0'
④如果num大于源字符串字符的个数,那么拷贝完源字符串的'\0'之后就结束了。
3、①函数strncmp
int strncmp(const char* str1,const char* str2,size_t num)
②模拟实现
#include<stdio.h>
typedef unsigned int size_t;
int my_strcmp(const char* str1, const char* str2,size_t num)
{
char* str = str1;
while (*str1 == *str2)
{
if (*str1 == '\0'||(str1-str)==num-1)
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char ch1[] = "abcdefe";
char ch2[] = "abcdefe";
int ret = my_strcmp(ch1, ch2,8);
if (ret > 0)
printf("第一个字符串大\n");
else if (ret < 0)
printf("第二个字符串大\n");
else
printf("两个字符串相等\n");
return 0;
}
③比较到两个字符不一样或者一个字符串结束或者num个全部比较完。
四、字符串查找
1、查看第二个字符串是不是第一个字符串的子串
①函数strstr()
char* strstr(const char* str1,const char* str2)
②模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1&&str2);
const char* s1 = str1;
const char* s2 = str2;
const char* cp = str1;
if (!*s2)
return (char*)str1;
while (*cp)
{
s1 = cp;
s2 = str2;
while (*s1&&*s2&&*s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
return (char*)cp;
cp++;
}
return NULL;
}
int main()
{
char ch1[] = "abcddefg";
char ch2[] = "cdde";
char* ret = my_strstr(ch1,ch2);
if (ret == NULL)
printf("字符串二不是字符串一的子串\n");
else
printf("字符串二是字符串一的子串\n%s\n",ret);
return 0;
}
2、分割字符串
①函数strtok()
char* strtok(char* str,const char* sep)
②函数的说明
<1>sep参数是个字符串,定义了用作分隔符的字符集合
<2>第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
<3>strtok函数找到str中的下一个标记,并将其用\0结尾,返回指向这个被截取的子字符串的首字符地址。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分字符串时一般都是临时拷贝一份)
<4>strtok函数的第一个参数不为NULL时,函数将找到str中第一个标记并且strtok函数将保存它在字符串中的位置。
<5>strtok函数的第一个参数为NULL时,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
<6>如果字符串中不存在更多的标记,则返回NULL指针。
③使用实例
#include<stdio.h>
#include<string.h>
int main()
{
char ch[] = "Millenfox@xx.1633";
char* ret = NULL;
for (ret = strtok(ch, "@."); ret != NULL; ret = strtok(NULL, "@."))
printf("%s\n", ret);
return 0;
}
五、错误信息报告
1、将错误码转化为错误信息的函数
①函数strerror()
char* strerror (int errno)
②库函数调用错误时都会产生一个错误码,将错误码放到一个全局变量int errno中。
③需要引用头文件#include<errno.h>
2、将错误码转化为错误信息后打印的函数
①函数perror()
void perror(const char* str)
②函数的作用:
<1>将错误码转化为错误信息
<2>打印错误信息(包括自定义的信息)
六、字符操作
1、字符分类函数
函数 | 如果它的参数符合下列条件就返回真(非0) |
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 | 任何可打印字符,包括图形字符和空白字符 |
2、字符转换
int tolower(int c);转化为小写字母
int toupper(int c);转化为大写字母