目录
一、字符串函数
(一)求字符串长度
strlen
size_t strlen( const char* str)
功能:所求字符串以'\0'为结束标志,返回值是字符串'\0'前面的字符个数(不包含'\0')
返回值:返回字符串的字符个数(不计算'\0')
注意:1.所求的字符串中必须包含'\0',但是在计算中,不需要计算'\0'
2.该函数的返回值是 size_t 类型的,是无符号的(易错)
函数实现:(1)计数器求解 (2)递归求解 (3)指针求解
//计数器求解
size_t my_strlen(const char* str)
{
assert(str);//断言
size_t num = 0;
while ( ( * str++) != '\0')
{
num++;
}
return num;
}
//递归求解
size_t my_strlen(const char* str)
{
assert(str);//断言
if (*str == '\0')
return 0;
else
return 1 + my_strlen(str + 1);
}
//指针求解
size_t my_strlen(const char* str)
{
assert(str);//断言
char* p = str;
while (*p)//判断*p!='\0',
{
p++;
}
return p-str;
}
int main()
{
char arr[] = "hello world!";
size_t len = my_strlen(arr);
printf("%zd\n", len);
return 0;
}
(二)长度不受限制的字符串函数
strcpy
char* strcpy ( char * dest , const char * s re );
功能:将src所指的字符串复制到dest
返回值:该函数返回一个指向最终目标字符串 dest 的指针
注意: 1.源字符串必须以'\0'为结束
2.在复制的过程中,会把源字符串的'\0'复制到目标字符串
3.目标空间要足够大,以便能够放下源字符串
4.目标字符串必须可变,不然无法复制
函数实现:
char* my_strcpy(char* dist, const char* src)
{
assert(dist && src);//断言,确保两个指针不为NULL
while (*dist++ = *src++)
{
;
}
return dist;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "hello world";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
strcat
char * strcat ( char * dest , const char * src );
功能:把 scr 所指向的字符串追加到 dest 所指向的字符串结尾
返回值:该函数返回一个指向最终目标字符串 dest 的指针
注意: 1.源字符串必须以'\0'为结束
2.在追加的过程中,会将源字符串的'\0'追加到目标字符串
3.目标空间要足够大,以便能够放下源字符串
4.目标字符串必须可变,不然无法追加
函数实现:
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);//断言
char* ret = dest;
//找到str1的末尾
while (*dest != '\0')
{
dest++;
}
//把str2 copy到 str1上
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "my\0*****************";
char arr2[] = "hello world!";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
strcmp
int strcmp ( const char * str1 , const char * str2 );
功能:比较两个字符串的大小 (区分大小写)
返回值:如果两个字符串相等 则返回0
如果 string1 小于 string2 则返回小于0的数字
如果 string1 大于 string2 则返回大于0的数字
注意:在返回大于0或者小于0的数字时,不同的编译器规定的不同,但是我们只要看返回值是否 大于0或者小于0 就可以了
函数实现:
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);//断言
while (*str1 == *str2)//比较字符相等,相等则进入循环
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
//字符不相等,返回两个字符相减值
return *str1 - *str2;
}
int main()
{
char arr1[20] = "abcdef";
char arr2[20] = "abcaefc";
int ret = my_strcmp(arr1, arr2);
if (ret == 0)
{
printf("arr1=arr2\n");
}
else if (ret < 0)
{
printf("arr1<arr2\n");
}
else
{
printf("arr1>arr2\n");
}
return 0;
}
(三)长度受限制的字符串函数
strncpy
char * strncpy ( char * dest, const char * src, size_t num );
功能:把 src 所指向的字符串复制到 dest,最多复制 num 个字符。当 src 的长度小于 num 时,dest 的剩余部分将用空字节填充
返回值:该函数返回最终复制的字符串
例如:
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[12];
memset(dest, '\0', sizeof(dest));
strcpy(src, "hello world!");
strncpy(dest, src, 7);
printf("最终的目标字符串: %s\n", dest);
return(0);
}
运行结果:
strncat
char * strncat ( char * dest, const char * src, size_t num );
功能:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,直到 num 字符长度为止
返回值:返回一个指向最终的目标字符串 dest 的指针
例如:
#include <stdio.h>
#include <string.h>
int main ()
{
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
strncat(dest, src, 15);
printf("最终的目标字符串: |%s|", dest);
return(0);
}
strncmp
char * strncmp (const char * str1, const char * str2, size_t num );
功能:strncmp用于比较两个字符串的前 num个字符是否相等,strcmp不限制比较的字符,strncmp最多只能比较num个字符,把 str1 和 str2 进行比较,最多比较前 num 个字符。
返回值:如果两个字符串相等 则返回0
如果 string1 小于 string2 则返回小于0的数字
如果 string1 大于 string2 则返回大于0的数字
例如:
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strncmp(str1, str2, 4);
if(ret < 0)
{
printf("str1 小于 str2");
}
else if(ret > 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
运行结果:
(四)字符串查找
strstr
char * strstr ( const char * str1 , const char * str2 );
功能:在字符串 str1 中查找第一次出现字符串 str2 的位置,不包含终止符 '\0'。
返回值:返回在 str1 中第一次找到 str2 的位置,没有找到则返回NULL
函数实现:
#include<stdio.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
const char* op ;//记录开始遍历的位置
const char* s1;//遍历str1
const char* s2;//遍历str2
//str2为空时
if (*str2 == '\0')
return str1;
//str2不为空时
op = str1;
while (*op)
{
s1 = op;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
return op;
op++;
}
return NULL;
}
int main()
{
char arr1[] = "abddeef";
char arr2[] = "dee";
char* ret = my_strstr(arr1, arr2);
printf("%s\n", ret);
//printf("%s\n", strstr(arr1, arr2));
return 0;
}
strtok
char * strtok ( char * str , const char * sep );
功能:以sep 分隔符集合中的分隔符,分解字符串 str 为一组字符串
返回值: 该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针
注意:1.sep参数是个字符串,定义了用作分隔符的字符集合 (sep不一定只是一个分隔符)
2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符 分割的标记
3.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它 在字符串中的位置。
4.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下 一个标记。
5.如果字符串中不存在更多的标记,则返回 NULL 指针
例如:
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "I-love.yuo!";
const char s[2] = "-.";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
return(0);
}
运行结果:
(五)信息错误报告函数
strerror
char * strerror ( int errnum );
功能:从内部数组中搜索错误号 errnum,并返回一个指向错误消息字符串的指针。(strerror 生 成的错误字符串取决于开发平台和编译器。)
返回值:该函数返回一个指向错误字符串的指针,该错误字符串描述了错误 errnum。
例如:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
FILE *fp;
fp = fopen("file.txt","r");
if( fp == NULL )
{
printf("Error: %s\n", strerror(errno));
}
return(0);
}
运行结果:
(六)内存操作函数
memcpy
void * memcpy ( void * dest , const void * src , size_t num );
功能:从src的位置开始向后复制num个字节的数据到dest的内存位置
参数:
- str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
- num -- 要被复制的字节数。
返回值:该函数返回一个指向目标存储区 dest 的指针
注意:1.这个函数在遇到 '\0' 的时候并不会停下来
2.如果src和dest有任何的重叠,复制的结果都是未定义的,memcpy一般都是对没有内存重叠的内存操作
函数实现:
void* my_memcpy(void* dest, const void* src,size_t num)
{
assert(dest && src);
char* ret = (char*)dest;
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = {0};
my_memcpy(arr2, arr1, 6);
printf("%s\n", arr2);
return 0;
}
memmove
void * memmove ( void * dest , const void * src , size_t num );
功能: 拥有和memcpy一样的功能,和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
参数:
- str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
- num -- 要被复制的字节数。
返回值:该函数返回一个指向目标存储区 dest 的指针
注意:如果源空间和目标空间出现重叠,就得使用memmove函数处理,尽量不要使用memcpy
函数实现:
void* my_memmove(void* dest, const void* src, size_t sz)
{
assert(dest && src);
char* ret = (char*)dest;
if (dest < src)
{
while (sz--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
while (sz--)
{
*((char*)dest + sz ) = *((char*)src + sz);
}
}
return ret;
}
int main()
{
char arr[] = "abcdefgh";
my_memmove(arr+2, arr , 4);
printf("%s\n", arr);
return 0;
}
memcmp
int memcmp ( const void * str 1 , const void * str 2 , size_t num );
功能:把存储区 str1 和存储区 str2 的前 num 个字节进行比较
参数:
- str1 -- 指向内存块的指针。
- str2 -- 指向内存块的指针。
- num -- 要被比较的字节数
返回值: 如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str1 大于 str2。
如果返回值 = 0,则表示 str1 等于 str2。
注意:memcmp函数比较的是从ptr1和ptr2指针开始的num个字节
二、字符分类函数
函数 | ||
iscntrl |
| |
isspace |
| |
isdigit | 十进制数字0~9 | |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F | |
islower | 小写字母a~z | |
isupper |
| |
isalpha | 字母a~z或A~Z | |
isalnum | 字母或数字a~z,A~Z或0~9 | |
ispunct | 标点符号,任何不属于数字或字母的图像字符(可打印符号) | |
isgraph | 任何图像字符 | |
isprint | 任何可打印字符,包括图像字符和空白字符 |