文章目录
前言
** c语言中对字符和字符串的处理很是繁琐,但是c语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。**
字符串常量适用于那些对它不做修改的字符串函数
-
长度不受限制的字符串函数
-
- strcpy()、strcat()、strcmp()
-
长度受限制的字符串函数介绍
-
可以越界执行
-
- strncpy、strncat、strncmp
-
字符串查找
-
- strstr、strtok
-
错误信息报告
-
- strerror
-
字符操作
一、strlen()
求字符串长度
使用strlen
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdef"; //abcdef\0
int len = strlen(arr);
printf("%d\n",len); //6
return 0;
}
模拟strlen
返回类型size_t 就是unsigned int 无符号整型
size_t my_strlen(const char* str)
{
size_t count = 0;
assert(str);
while (*str != 0)
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
size_t n = my_strlen(arr);
printf("%u\n", n);
return 0;
}
sttrlen使用时的小细节
强制转换和比大小是可以的
int main()
{
if(strlen("abc")-strlen("abcdef")>0)
{
printf(">\n");
}
else
{
printf("<=\n");
}
result >
因为是无符号整型
return 0;
}
二、strcpy()
-
字符串拷贝
-
遇到 \0 停止
-
不能拷贝字符
-
char arr[ ] = { ‘b’,‘i’,‘t’ };
-
不知道什么时候会碰到 \0
-
源字符必须以 ‘\0’ 结束
-
目标空间必须足够大,以确保能存放原字符串。
-
目标空间必须可变
int main()
{
char name[20] = { 0 };
//"huheng"
char a[] ="huheng";
这两种都可以
strcpy(name,a);
strcpy(name,"huheng");
printf("%s\n",name);
return 0;
}
模拟实现strcpy
#include<assert.h>
char* my_strcpy(char* dest,const char* src)
{
assert(dest && src);
char* ret = dest;
while(*dest++ = *src++)
;
return ret;
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
三、strcat()
字符串追加
- 源字符必须以 ‘\0’ 结束
- 目标空间足够大
- 目标空间可修改
- 不能自己给自己追加
#include<string.h>
int main()
{
char arr[20] = "hello";
strcat(arr,"world");
printf("%s\n",arr);
hello world
return 0;
}
模拟实现strcat
- 找到目标字符串的结尾 \0
- 拷贝
#include<string.h>
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest && src);
while (*dest != '\0')
{
dest++;
}
while (*dest++ = *src++)
;
return ret;
}
int main()
{
char arr[20] = "hello";
my_strcat(arr, " world");
printf("%s\n", arr);
return 0;
}
四、strcmp()
strcmp比较两个字符串的内容大小
数组名是数组首元素的地址
这个结果是 !=
因为比较的是地址
#include<string.h>
int main()
{
char arr1[20] = "zhangsan";
cahr arr2[] = "zhangsanfeng";
if(arr1 == arr2)
{
printf("==\n");
}
else
{
printf("!=\n");
}
return 0;
}
两个字符串相比较应该使用
strcmp()
比较的是ascll码
#include<string.h>
int main()
{
char arr1[20] = "zhangsan";
char arr2[] = "zhangsanfeng";
int ret = strcmp(arr1,arr2);
if(ret<0)
{
printf("arr1 < arr2\n");
}
else if(ret ==0)
{
printf("arr1 == arr2\n");
}
else
{
printf("arr1 > arr2\n");
}
}
模拟实现strcmp
这个也可以
int my_strcmp(const char* str1,const char*str2)
{
assert(str1 && str2)
while(*str1 == *str2)
{
if(&str1 == '\0')
return 0;
str2++;
str2++
}
if(*str1 > *str2)
return 1;
else
return -1;
这个样子也可以替代后面的if函数
return (*str1-*str2);
}
int main()
{
char arr1[20] = "zhangsan";
char arr2[] = "zhangsanfeng"
if (ret < 0)
{
printf("arr1 < arr2\n");
}
else if (ret == 0)
{
printf("arr1 == arr2\n");
}
else
{
printf("arr1 > arr2\n");
}
return 0;
}
五、strncpy()
strncpy的使用
strncpy(arr1,arr2,5);
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "hello bit";
strncpy(arr1, arr2, 5);
覆盖五个元素
printf("%s\n", arr1);
return 0;
}
六、strncat()
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
strncat(arr1,arr2,5);
printf("%s\n",arr1);
return 0;
}
七、strncmp()
== 0
> 1
<- 1
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abc";
int ret = strncmp(arr1,arr2,3);
printf("%d\n",ret);
}
八、strstr(字符串查找)
字符串查找’
kmp算法
int main()
{
char email[] = "hh@bitejiuyeke.com";
char substr[] = "bitejiuyeke";
char* ret = strstr(email, substr);
if (ret == NULL)
{
printf("字串不存在\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
strstr的实现
#include<assert.h>
char* my_strstr(char* str1, char* str2)
{
assert(str1 && str2);
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;
while (*p)
{
s1 = p;
s2 = str2;
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)p;
}
p++;
}
return NULL;
}
int main()
{
char email[] = "hh@bitejiuyeke.com";
char substr[] = "bitejiuyeke";
char* ret = my_strstr(email, substr);
if (ret == NULL)
{
printf("字串不存在\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
九、strtok
切割字符串
strtok的使用
int main()
{
const char* sep = "@.";
char email[] = "huheng@bitejiuyeke.com";
char cp[30] = { 0 };
strcpy(cp,email);
char* ret = strtok(cp,sep);
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);
return 0;
}
int main()
{
const char* sep = "@.";
char email[] = "huheng@bitejiuyeke.com";
char cp[30] = { 0 };
strcpy(cp,email);
char* ret = NULL;
for(ret = strtok(cp,sep);
ret!=NULL;
ret = strtok(NULL,sep)
)
{
printf("%s\n",ret);
}
char* ret = strtok(cp,sep);
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);
ret = strtok(NULL, sep);
printf("%s\n", ret);
return 0;
}
十、strerror
c预言的库函数,再执行失败的时候,都会设置错误码
strerror 就是返回错误码所对应的错误信息。
int main()
{
printf("%s\n",streeror(0));
printf("%s\n",streeror(1));
printf("%s\n",streeror(2));
printf("%s\n",streeror(3));
}
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt","r");
if(pf == NULL)
{
printf("%s\n",strerror(errno));
return 1;
}
fclose(pf);
pf = NULL;
return 0;
}
peror打印错误信息
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fclose(pf);
pf = NULL;
return 0;
}