目录
一、字符串函数
1、求字符串长度
strlen
size_t strlen(const char * str):求字符串的长度
注意:
- 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包
- 含 '\0' )。
- 参数指向的字符串必须要以 '\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;
}
//由于strlen()函数的返回值类型为无符号整型,两数相减总是大于0
//代码的运行结果为str1>str2
strlen()函数的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strlen(const char* str)
{
assert(str);
char* start = str;
char* end = str;
while (*end != '\0')
{
end++;
}
return end - start;
}
int main()
{
char* arr = "123jud";
printf("%d", my_strlen(arr));
return 0;
}
运行结果:
2、长度不受限制的字符串函数
strcmp
char* strcpy ( char * destination , const char * source ):将原字符串复制到目标字符串
注意:
- 原字符串必须以'\0'结尾
- strcpy()在复制原字符串时,会将原字符串中的‘\0’也会复制到目标字符串
- 要确保目标字符串有足够大的空间
- 要确保目标空间可变
strcpy()函数的模拟实现
char* my_strcpy(char* str1, const char* str2)
{
assert(str1);
assert(str2);
char* s = str1;
while (*str1++ = *str2++)
{
;
}
return s;
}
int main()
{
char arr1[18]= "123jud";
char arr2 [5]= "uip";
printf("%s\n", my_strcpy(arr1, arr2));
return 0;
}
运行结果:
strcat
char * strcat ( char * destination , const char * source ):将原字符串拼接到目标字符串之后
注意:
- 源字符串必须以 '\0' 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
- 字符串不能给自己追加:因为在原字符串的‘\0’开始追加,但是当再次准备将'\0'向后追加是,‘\0’已经被原字符串的第一个字母覆盖,这样就不会再有‘\0’,导致陷入无限循环。
strcat()函数模拟实现
char* my_strcat(char* str1, const char* str2)
{
assert(str1);
assert(str2);
char* s = str1;
while (*str1)
{
str1++;
}
while (*str2)
{
*str1++ = *str2++;
}
return s;
}
int main()
{
char arr1[18]= "123jud";
char arr2 [5] = "uip";
printf("%s\n", my_strcat(arr1,arr2));
return 0;
}
运行结果:
strcmp
int strcmp ( const char * str1 , const char * str2 ):判断两个字符串的大小
注意:
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
- 字符串的比较与字符串的长度无关,注重的是字符串中字符的相应比较
strcmp函数模拟实现
int my_strcmp(const char* str1, const char* str2)
{
assert(str1);
assert(str2);
while (*str1== *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
char arr1[18]= "vd";
char arr2 [5] = "jud";
printf("%d\n", my_strcmp(arr1,arr2));
return 0;
}
运行结果:
3、长度受限制的字符串函数
strncpy
char * strncpy ( char * destination , const char * source , size_t num ):拷贝 num 个字符从源字符串到目标空间。
注意:
- 该函数在追加完num个字符之后,不会主动地加'\0'的。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
strncpy()函数模拟实现
char* my_strncpy(char* dest, const char* src,int num)
{
assert(dest);
assert(src);
char* ret = dest;
int i = 0;
while (i<num&&*src!='\0')
{
*dest++ = *src++;
i++;
}
if (i = num)
{
*dest = '\0';
}
if (*src=='\0')
{
while (i < num)
{
*dest++ = 0;
i++;
}
}
return ret;
}
int main()
{
char arr1[20] = "abcdefghi";
char arr2[] = "xxxx";
printf("%s\n", my_strncpy(arr1, arr2, 3));
return 0;
}
运行结果:
strncat
char * strncpy ( char * destination , const char * source , size_t num ):拷贝 num 个字符从源字符串到目标空间之后。
注意:
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
- strncpy可以实现将自身追加到后面,因为该函数在追加上num个字符之后,会主动加上'\0'。
strncpy()函数模拟实现
char* my_strncpy(char* str1, const char* str2, int num)
{
assert(str1);
assert(str2);
char* s = str1;
int i = 0;
while (*str1)
{
str1++;
}
while (i < num && *str2 != '\0')
{
*str1++ = *str2++;
i++;
}
if (*str2 == '\0')
{
while (i <num)
{
*str1++ = 0;
i++;
}
}
*str1 = '\0';
return s;
}
int main()
{
char arr1[18]= "vd";
char arr2 [5] = "jud";
printf("%s\n", my_strncpy(arr1,arr2,2));
return 0;
}
运行结果:
strncmp
int strncmp ( const char * str1 , const char * str2 , size_t num ):对str1和str2的num个字符进行比较
注意:
- 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
strncmp()函数模拟实现
int my_strncmp(const char* str1, const char* str2, int num)
{
assert(str1);
assert(str2);
int i = 0;
while (*str1 == *str2&&i<num)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
i++;
}
if (i == num)
{
return 0;
}
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
char arr1[20] = "1bcdefghi";
char arr2[] = "0xxx";
printf("%d\n", my_strncmp(arr1, arr2, 3));
return 0;
}
运行结果:
4、字符串查找函数
strstr
char * strstr ( const char * str1 , const char * str2 ):在字符串str1找到字符串str2第一次出现的位置,不包含'\0'
strstr()函数的模拟实现
char* my_strstr(const char* str1, const char* str2)
{
assert(str1);
assert(str2);
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;
if (*str2 == '\0')
{
return (char*)str1;
}
while (*p)
{
s1 = p;
s2 = str2;
while (*s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)p;
}
p++;
}
return NULL;
}
int main()
{
char arr1[20] = "189h1euihgh688";
char arr2[] = "1euihgh";
printf("%p\n", my_strstr(arr1, arr2));
return 0;
}
运行结果:
strtok
char * strtok ( char * str , const char * sep ):用sep所指的字符串中的单个字符作为分隔符,将str所指的字符进行分隔
注意:
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割标记。
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
strtok()函数应用演示
int main()
{
char str1[20] = "nbswio*123^ok";
const char* str2= "*^";
char* p = str1;
for (p = strtok(str1, str2); p != NULL; p = strtok(NULL, str2))
{
printf("%s\n", p);
}
return 0;
}
运行结果:
5、错误信息报告函数
strerror
char * strerror ( int errnum );
strerror()函数应用演示
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pFile;
pFile = fopen("unexist.ent", "r");
if (pFile == NULL)
printf("错误信息显示: %s\n", strerror(errno));
return 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 | 任何可打印字符,包括图形字符和空白字符 |
字符转换:
int tolower(int c):将c转换为小写
int toupper(int c):将c转换为大写
应用演示(将字符串的小写字母全部转换为大写)
#include<stdio.h>
#include<ctype.h>
int main()
{
char str[] = "we aT HoMe";
for (int i = 0; i < sizeof(str); i++)
{
int c = str[i];
int d=toupper(c);
putchar(d);
}
return 0;
}
运行结果: