字符函数和字符串函数

登山则情满于山,观海则意溢于海。这篇文章主要讲述字符函数和字符串函数相关的知识,希望能为你提供帮助。
???前言???
???C语言中对字符和字符串的处理很频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中字符串常量适用于那些对它不能做修改的字符串函数。???
?函数介绍???strlen
?计算字符个数

size_t strlen(const char* str)

strlen库函数的使用
#include< string.h> //注意引头文件
int main()

char arr[] = "abcdef";
int ret=strlen(arr);
printf("%d\\n", ret);

return 0;


注意事项?*?字符串以\\0做为结束标志,strlen函数返回的是在字符串中‘\\0前面出现的字符个数(不包含’\\0);
?*?参数指向的字符串必须要以‘\\0结束
#include< string.h>
int main()

//错误示范
char arr[] =a,b,c,d,e ;
int ret = strlen(arr);
printf("%d\\n", ret);


return 0;


?*?函数的返回类型是size_t;
#include< stdio.h>
#include< string.h>
int main()

if (strlen("abc") - strlen("abcdef")> 0)

printf("haha");

else

printf("hehe");


return 0;


输出hehe的原因:strlen函数的本来返回类型是无符号(unsigned int )是通过(typedef)进行类型重定义成(size_t);
*模拟实现strlen1.计数器的方式实现思路:通过指针寻找’\\0,直到找到‘\\0时结束while循环
#include< assert.h> //断言时注意头文件
#include< stdio.h>
//因为字符串是常量字符串所以用const修饰防止被改
int my_strlen(const char* str)

assert(str != NULL); //断言指针,如果为空指针则会报错
int count = 0;
while (*str != \\0)

count++;
str++;

return count;

int main()


int len = my_strlen("abcdef");
printf("%d\\n", len);
return 0;




2.递归的方式思路:通过递归的方式不断调用自己
特点:不创建临时变量
#include< stdio.h>
#include< assert.h>
int my_strlen(const char* str)

assert(str!=NULL);
if (*str != \\0)
return 1 + my_strlen(str + 1);
else
return 0;

int main()

char arr[] = "bit";
int len = my_strlen(arr);
printf("len =%d", len);
return 0;


3.指针减指针的方式思路:指针减指针得到是中间元素的个数
#include< stdio.h>
#include< assert.h>
int my_strlen(const char* str)

assert(str!=NULL);
char* start = str;
char* end = start;
while (*end != \\0)

end++;

return end - start;

int main()

char arr[] = "bit";
int len = my_strlen(arr);
printf("%d\\n", len);
return 0;


?strcpy
?字符串拷贝
char* strcpy(char* destination,const char* source);

?strcpy?库函数的使用
#include< stdio.h>
#include< string.h>
int main()

char arr1[] = "abcde";
char arr2[] = "bit";

strcpy(arr1,arr2);
printf("%s\\n", arr1);
return 0;


注意事项?*源字符串必须以’\\0结束
int main()

char arr1 []= "abcdef";
char arr2 []=a,b,c ;
strcpy(arr1, arr2);
return 0;


?*会将源字符串中的‘\\0拷贝到目标空间
*?目标空间必须足够大,以确保能存放源字符串
#include< stdio.h>
#include< string.h>
int main()

char arr1[5] = "abc";
char arr2[] = "hello";
strcpy(arr1, arr2);
printf("%s\\n", arr1);
return 0;


?*目标空间必须可变
#include< string.h>
int main()

char arr1 []= "abcdef";
char* arr2[] = "bit";
strcpy(arr1, arr2);
return 0;


模拟实现strcpy
#include< assert.h>
#include< stdio.h>
char* my_strcpy( char* dest, const char* src)

assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
//拷贝src指向的字符串到dest指向的空间,包含\\0
while (*dest++ = *src++)

;


//返回目的地空间的起始位置;
return ret;

int main()

char arr1[] = "abcde";
char arr2[] = "bit";
my_strcpy(arr1, arr2);
printf("%s\\n", arr1);
return 0;


strcat?
?字符串追加
char* strcat(char* destination,const char* source)

strcat库函数的使用
#include< stdio.h>
#include< string.h>
int main()

char arr1[20] = "hello";
char arr2[10] = "world";
strcat(arr1, arr2);
printf("%s\\n", arr1);
return 0;

  注意事项?*源字符串必须以’\\0结束;
#include< stdio.h>
#include< string.h>
int main()

char arr1[20] = "hello";
char arr2[10] =a,b,c ;
strcat(arr1, arr2);
printf("%s\\n", arr1);
return 0;


注:程序奔溃了
?*会将源字符串的‘\\0追加过去
#include< stdio.h>
#include< strimg.h>
int main()

char arr1[30] = "hello\\0xxxxxxx";
char arr2[] = "bit";
strcat(arr1, arr2);
printf("%s\\n", arr1);
return 0;


?*目标空间必须足够大,能容纳源字符串的内容;
#include< string.h>
#include< stdio.h>
int main()

char arr1[] = "hello";
char arr2[] = "bit";
strcat(arr1, arr2);
printf("%s\\n", arr1);
return 0;




?*目标空间必须可以修改;
#include< stdio.h>
#include< string.h>
int main()

char arr1[20] = "hello";
char* arr2[10] = "world";
strcat(arr1, arr2);
printf("%s\\n", arr1);
return 0;


模拟实现strcat
#include< assert.h>
#include< stdio.h>
char* my_strcat(char* dest,const char* src)

char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
//1.找到目的地字符串的\\0
while (*dest != \\0)

dest++;

//2.字符串拷贝
while (*dest++ = *src++)

;

return dest;


int main()

char arr1[30] = "hello";
char arr2[] = "bit";
my_strcat(arr1, arr2);
printf("%s\\n", arr1);

return 0;


??strcmp?
?字符串比较
int strcmp(const char* destination,const char* source)

?strcmp库函数的使用标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第二个字符串小于第一个字符串,则返回小于0的数字;
#include< stdio.h>
#include< string.h>
int main()

char arr1[10] = "abc";
//若第一个相同,则到下一个进行比较
char arr2[10] = "qwe";
int ret=strcmp(arr1, arr2);
printf("%d", ret);
return 0;


模拟实现strcmp

#include< stdio.h>
#include< assert.h>
int my_strcmp(const char* str1, const char* str2)

assert(str1 != NULL);
assert(str2 != NULL);
//比较
while (*str1 == *str2)

if (*str1 == \\0)

return 0;

str1++;
str2++;

return (*str1 - *str2);

int main()

const char* p1 = "abcdef";
const char* p2 = "abcqwe";
int ret = my_strcmp(p1, p2);
printf("%d", ret);
return 0;


?strncpy??
字符串拷贝
char* strncpy(char* destination,const char* source,size_t num)

strncpy库函数的使用
#include< stdio.h>
#include< string.h>
int main()

char arr1[10] = "abcdef";
char arr2[] = "hello";
strncpy(arr1, arr2,4);
printf("%s", arr1);

return 0;


注意事项?*拷贝num个字符从源字符串到目标空间;
?*如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加\\0,直到num个;

?strncat?
?字符串追加
char* strncat(char* destination,const char* source,size_t num)

strncat库函数的使用
#include< stdio.h>
#include< string.h>
int main()

char arr1[10] = "abcde";
char arr2[7] = "hello";
strncat(arr1, arr2, 4);
printf("%s", arr1);
return 0;


?strncmp?
?字符串比较
int strcmp(const char*string1.h,const char* string2.h,size_t count)

?strncmp库函数的使用
#include< stdio.h>
#include< string.h>
int main()

const char* p1 = "abcde";
const char* p2 = "abcqwer";
int ret=strncmp(p1, p2, 4);
printf("%d", ret);
return 0;


?strstr
?查找子字符串
char*strstr(const char* string,const char* strcharset);

strstr库函数的使用使用说明:如果查找的子字符串不存在则返回NULL
#include< stdio.h>
#include< string.h>
int main()

char* p1 = "abcdef";
char* p2 = "def";
//p1是被查找的字符串
//p2是要查找的字符串
char* ret = strstr(p1, p2);
if (ret == NULL)

printf("子字符串不存在\\n");

else

printf("%s\\n", ret);

return 0;


strstr模拟实现
#include< stdio.h>
#include< assert.h>
char* my_strstr(const char* p1, const char* p2)

assert(p1 != NULL);
assert(p2 != NULL);
char* s1 = p1;
char* s2 = p2;
char* cur = p1;
if (*p2 == \\0)

return p1;

while (*cur)

s1 = cur;
s2 = p2;
while ((*s1 != \\0) & & (*s2 != \\0) & & (*s1 == *s2))

s1++;
s2++;

if (*s2 == \\0)

return cur; //找到子串

if(*s1==\\0)

return NULL;

cur++;

return NULL;


int main()

char* p1 = "abcdef";
char* p2 = "def";

char* ret = my_strstr(p1, p2);
if (ret == NULL)

printf("子字符串不存在\\n");

else

printf("%s\\n", ret);

return 0;


?strtok
char* strtok(char* str,const char* sep);

strtok库函数的使用使用说明:sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用\\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。如果字符串中不存在更多的标记,则返回NULL指针
?举例说明?
#include< stdio.h>
#include< assert.h>
#include< string.h>
int main()

char arr[] = "myl@lcy.stu";
char* p = "@.";
char buf[20] =0 ;
strcpy(buf, arr);
char* ret = strtok(arr, p);
printf("%s\\n", ret);

ret = strtok(NULL, p);
printf("%s\\n", ret);

ret = strtok(NULL, p);
printf("%s\\n", ret);

return 0;


?恰当的使用方法?
#include< stdio.h>
#include< assert.h>
#include< string.h>
int main()

char arr[] = "myl@lcy.stu";
char* p = "@.";
char buf[20] =0 ;
strcpy(buf, arr);
char* ret = NULL;
for (ret = strtok(arr, p); ret != NULL; ret = strtok(NULL, p))

printf("%s\\n", ret);


return 0;


?strerror
?错误报告函数
char* strerror(int errnum);

strerror库函数的使用使用说明:
char* p = strerror(errno);
errno 是一个全局的错误码的变量
当c语言的库函数在执行过程中,发生了错误,就会把对应的错误码,赋值到errno中
#include< stdio.h>
#include< string.h>
#include< errno.h> //注意引头文件
int main()

//char *p= strerror(0); //No error
//char* p = strerror(1); //Operation not permitted
printf("%s\\n", p);
return 0;



错误码         错误信息

0              No error

1               Operation not permitted

2             ......
举例:打开文件
#include< stdio.h>
#include< string.h>
#include< errno.h> //注意引头文件
int main()


FILE* pf = fopen("test.txt", "r");
if (pf == NULL)

printf("%s\\n", strerror(errno));

else

printf("打开成功\\n");

return 0;


字符分类函数
函数如果它的参数符合下列条件就返回真
iscntrl    任何控制字符
isspace  空白字符:空格‘ ’,换页‘\\f’,换行\\n,回车‘\\r’,制表符\\t或者垂直制表符\\v
isdigit  十进制数字
0~9isxdigit  十六进制数字,包括所有十进制数字,小写字母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); //小写

int tolower(int c)//大写

使用
#include< stdio.h>
#include< ctype.h> //注意引头文件
int main()

char arr[20] = "I Am A Student";
int i = 0;
while (arr[i])

if (isupper(arr[i]))

arr[i] = tolower(arr[i]);

i++;

printf("%s\\n", arr);


return 0;


?memcpy
?内存拷贝
void *memcpy(void* destination,const void* source,size_t num);

memcpy库函数的使用?*?函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
#include< stdio.h>
#include< string.h>
int main()

int arr1[5] =1,2,3,4,5 ;
int arr2[5] =0 ;
memcpy(arr2, arr1, sizeof(arr1));

return 0;


?*?这个函数在遇到\\0的时候并不会停下来。
?*?如果source和destination有任何的重叠,复制的结果都是未定义的。
模拟实现memcpy
#include< assert.h>
void* my_memcpy(void* dest, const void* src, int num)

void* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (num--)

*(char*)dest =*(char*)src;
++(char*)dest;
++(char*)src;

return ret;

int main()

int arr1[5] =1,2,3,4,5 ;
int arr2[5] =0 ;
my_memcpy(arr2, arr1, sizeof(arr1));

return 0;


?memmove?
处理重叠内存拷贝?
void* memmove(void* destination,const void* source,size_t num);

memove库函数的使用使用说明:如果源空间和目标空间出现重叠,就得用memmove函数实现
#include< string.h>
#include< stdio.h>
int main()

int arr[10] =1,2,3,4,5,6,7,8,9,10 ;
memmove(arr + 2, arr, 20);
int i = 0;
for (i = 0; i < 10; i++)

printf("%d ",arr[i]);


return 0;


模拟实现memmove
#include< stdio.h>
#include< assert.h>
void* my_memmove(void* dest, const void* src, int k)

void* ret = dest;
assert(dest != NULL);
assert(src != NULL);
if (dest < src)//从前向后拷贝

while (k--)

*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;


else

while (k--)

*((char*)dest + k) = *((char*)src + k); //从后向前拷贝



return ret;

int main()

int arr[10] =1,2,3,4,5,6,7,8,9,10 ;
my_memmove(arr + 2, arr, 20);
int i = 0;
for (i = 0; i < 10; i++)

printf("%d ",arr[i]);


return 0;


?memcmp
?内存比较
void * memcpy ( void * destination, const void * source, size_t num );

memcmp库函数的使用
#include< stdio.h>
int main()

int arr1[] =1,2,3,4,5 ;
int arr2[] =1,2,5,4,3 ;
int ret=memcmp(arr1, arr2, 9);
printf("%d", ret);
return 0;


?memset
?内存设置
void* memset(void* dest,int c,size_t count);

int c:改的内容
size_t count:改的字节数
memset库函数的使用
int main()

char arr[10] = "";
memset(arr, *, 10);

return 0;


【字符函数和字符串函数】继续加油,用代码撬动世界

    推荐阅读