前言:
哈哈,首先祝贺你,当你点击打开这个 字符函数与字符串函数这个专栏的时候,你已经不是一名摸鱼崽了
你是积极学习的榜样,哈哈,那让我们一起开始新知识的探索吧!
不难发现,C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在
常量字符串 中或者 字符数组 中。 字符串常量 适用于那些对它 不做修改的字符串函数.那今天我们就从常见的
字符串函数功能以及部分函数的模拟实现开始吧。
长度不受限字符串函数
1.strlen
1.1strlen(求字符串长度)
1.1.2strlen函数的声明
strlen函数是计算一个字符串的长度
size_t strlen ( const char * str );
- 函数返回值是size_t(无符号整型);
- 字符指针str指向的字符串必须包含’\0’;
- 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ ).
1.1.3如何使用strlen函数以及易错用法
#include<stdio.h>
#include<string.h>
int main()
{
char arr[10] = "abcdefg";//定义一个长度为7的字符串
int lenth = strlen(arr);//计算字符串长度
printf("该字符串的长度为%d", lenth);//打印长度7
return 0;
}
因为该函数返回值为size_t所以很多同学容易会出现下方错误用法
#include <stdio.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if(strlen(str2)-strlen(str1)>0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
在这里输出结果始终为str2>str1,因为是两个无符号整数进行运算,不可能出现负数
1.1.4strlen函数的模拟实现
size_t my_strlen(const char* str)
{
int count = 0;
while (*str++)
{
count++;
}
return count;
}
2.strcmy
2.1strcpy(复制字符串内容)
2.1.1stcpy函数的声明
char* strcpy(char * destination, const char * source )
- 源头字符串必须以 ‘\0’ 结束。
- 源头字符串会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
2.1.2stcpy函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
char desnation[20] = "asd";//目标字符串数组
char arr[10] = "abcdefg";//源头数组
strcpy(desnation, arr);
printf("%s", desnation);//打印
return 0;
}
2.1.3stcpy函数的模拟实现
#include<stdio.h>
char* my_strcpy(char* des, const char* arr)
{
char* start = des;//由于des指针会在拷贝过程中发生改变,所以要存下首元素地址
while (*des++ = *arr++)
{
;
}
return start;
}
3.strcat
3.1strcat(追加字符串内容)
3.1.1strcat函数的声明
char * strcat ( char * destination, const char * source );
- 源字符串必须以 ‘\0’ 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
3.1.2strcat函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
char des[15] = "abcd";
char arr[10] = "efgh";
strcat(des, arr);//给des数组中字符串数组追加"efgh"
printf("%s", des);
return 0;
}
3.1.3strcat函数的模拟实现
my_strcat(char* des, const char* arr)
{
char* p = des;
while (*des!='\0')
{
des++;
}
while (*des++ = *arr++)
{
;
}
return p;
}
strcat函数能否实现字符串的自我追加
我们来讨论一个有趣的问题,strcat函数可以如下使用吗?
#include<stdio.h>
#include<string.h>
int main()
{
char des[15] = "abcd";
strcat(des, des);//给des数组中字符串数组追加"efgh"
printf("%s", des);
return 0;
}
答案是不可以,那为什么呢?,因为呀strcat函数要实现追加字符串的功能,那就必须找到,被追加字符串的结尾’\0’
并以直到源头字符串’\0’结束,如果是同一字符串,则在拷贝的过程中,该字符串长度不断变长,源头字符串原来的’\0’
被覆盖,永远也结束不了。
4.strcmp
4.1strcmp(字符串比较)
4.1.1strcmp函数的声明
int strcmp ( const char * str1, const char * str2 );
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
4.1.2strcmp函数的使用
#include<string.h>
#include<stdio.h>
int main()
{
char des[15] = "asas";
char arr[15] = "bcbc";
int i=strcmp(des, arr);
printf("%d", i);
return 0;
}
4.1.3strcmp函数的模拟实现
int my_strcmp(const char* des, const char* arr)
{
while (*des == *arr)
{
if (*des == 0)
{
return 0;
}
des++;
arr++;
}
return *des - *arr;
}
5.strstr
5.1strstr(子字符串查找)
5.1.1strstr函数的声明
char * strstr ( const char *str1, const char * str2);
- 子串为空字符串时,返回str1
- str1为空字符串时,找不到子串,返回NULL
5.1.2strstr函数的使用
#include<string.h>
#include<stdio.h>
int main()
{
char des[15] = "abcdf";
char *ch = NULL;
ch = strstr(des, "cd");
printf("%s", ch);
return 0;
}
5.1.3strstr函数的模拟实现
//KMP算法
char* my_strstr(const char* str1, const char* str2)
{
if (*str2 == '\0')
{
return (char*)str1;
}
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;
while (*p)
{
s2 = str2;
s1 = p;
while (*s2 && *s1 && *s2 == *s1)
{
s2++;
s1++;
}
if (*s2 == '\0')
{
return (char*)p;
}
p++;
}
return (NULL);
}
6.strtok
6.1strtok(分割字符串)
6.1.1strtok函数的声明
char * strtok ( char * str1, const char * str2);
- str2参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由str2字符串中一个或者多个分隔符分割的标记。
- 函数找到str1中的第一个分隔符,并将其用 \0 结尾,返回一个指向该分割字符串的指针。(注:strtok函数会改变被操作的字符串,所以要对查找字符串进行临时拷贝)
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。如果字符串中不存在更多的标记,则 返回 NULL 指针。
6.1.2strtok函数的使用
#include<string.h>
#include<stdio.h>
int main()
{
char str1[15] = "abb@bc@bh,h.j";
char str2[15] = "@,.";
for (char* ch = strtok(str1, str2); ch != NULL; ch=strtok(NULL, str2))
{
printf("%s\n", ch);
}
return 0;
}
此函数是一个比较难理解的函数,所以要理解清楚,否则连用都不知道怎么用的,就很尴尬
7.strerror
7.1strerror(翻译错误码信息)
7.1.1 strerror函数的声明
char * strerror ( int errnum );
- 使用错误码时需引用头文件<errno.h>
- 使用库函数时,如果调用失败,都会设置错误码
- 每个错误码包含一个错误信息
7.1.2 strerror函数的使用
打印错误码信息,也可以用perror()函数直接打印错误信息
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须引用的头文件
int main ()
{
FILE * pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("打开文件失败原因是: %s\n",strerror(errno));
return 0;
}
长度受限字符串函数
1.1strncpy
1.1.1 strncpy函数的声明
char * strncpy ( char * destination, const char * source, size_t num );
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
1.1.2strncpy函数的使用
#include<string.h>
#include<stdio.h>
int main()
{
char des[15] = "asas";
char arr[15] = "dsfds";
strncpy(des, arr, 1);
printf("%s", des);
return 0;
}
1.2strncat
1.2.1strncat函数的声明
char * strncat ( char * destination, const char * source, size_t num );
1.2.2strncat函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
char dest[15] = "abcdefgh";
char source[15] = "gfg";
printf("%s\n", strncat(dest, source,3));
return 0;
}
1.3strncmp
strncmp函数的声明
int strncmp ( const char * str1, const char * str2, size_t num );
strncmp函数的声明
#include<stdio.h>
#include<string.h>
int main()
{
char str1[15] = "jhj";
char str2[15] = "ijhdef";
printf("%d\n", strncmp(str1, str2,5));
return 0;
}
🎉***好啦常用的的字符串函数就是这些,如果这都不算难的话,那下一篇的字符函数和内存函数就更简单了***