库函数,是用来求字符串长度的
本质上统计的是字符串中\0之前的字符的个数
使用前包含头文件:#include
#include
#include
int main()
{
const char* str = "abcdef";
size_t len1 = strlen("abcdef");
size_t len2 = strlen(str);
printf("%d\n", len1);//6
printf("%d\n", len2);//6
return 0;
}
#include
#include
int my_strlen(const char* str)
{
assert(str != NULL);
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
int main()
{
char str[] = "abcdef";
int len = my_strlen(str);
printf("%d", len);
return 0;
}
strlen返回值是无符号整型size_t
可以体现在以下代码:打印结果为>=
int main()
{
//两个无符号数相减得到的还是无符号数
// 3 - 6
//-3
//10000000000000000000000000000011
//11111111111111111111111111111100
//11111111111111111111111111111101
//
if (strlen("abc") - strlen("abcdef") > 0)
printf(">=\n");
else
printf("<\n");
return 0;
}
用于拷贝字符串(包含\0)
源字符串必须以\0结尾
目标空间必须足够大,以确保能存放源字符串
目标空间必须可变
int main()
{
char* p="abcdef";
char* arr2[]="hello";
strcpy(p,arr2);//err:这里的p目标空间不可变
printf("%s\n",p);
return 0;
}
#include
#include
void my_strcpy(char* dest, char* src)
{
while (*src != '\0')
{
*dest++ = *src++;
}
*dest = *src; //拷贝\0
}
int main()
{
char arr1[20] = "****************";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
用于字符串的合并,有两个参数,后者合并到前者
arr2首元素会把arr1的“\0”覆盖
注意:
1.目标空间必须足够大,还需要可以修改
2.目标空间必须有\0,保证能找到目标空间的末尾
3.源字符串也得有\0,在拷贝时将源字符串中的\0拷贝过去
#include
#include
int main()
{
char arr1[20] ="abc";
char arr2[] = "def";
strcat(arr1,arr2);
printf("%s\n",arr1);//打印结果是abcdef
return 0;
}
返回的是目标空间的起始地址
#include
#include
#include
char* my_strcat(char*dest,const char*src)
{
assert(dest && src);
//1.找到目标空间末尾
if(*dest!='\0')
{
dest++;
}
//2.字符的追加(和strcpy思路一样)
while(*dest++ = *src++)
{
;
}
}
int main()
{
char arr1[20] ="abc";
char arr2[] = "def";
my_strcat(arr1,arr2);
printf("%s\n",arr1);//打印结果是abcdef
return 0;
}
注意:
strcat自己给自己追加,会将\0覆盖掉,可能陷入死循环,应该尽量避免
用于字符串的比较
比较原理:对应位置上字符的大小(ASCII值)
例如:
字符串1: a b c d e f
字符串2:a b q
由于‘c’<‘q’,就说字符串2大于字符串1
定义:int strcmp(const char* str1,const char* str2)
int main()
{
char arr1[] = "abc";
char arr2[] = "abq";
if(strcmp(arr1,arr2)>0)
{
printf(">\n");
}
else if(strcmp(arr1,arr2)==0)
{
printf("=\n");
}
else
{
printf("<\n");
}
return 0;
}
模拟实现strcmp-----my_strcmp
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[] = "abc";
char arr2[] = "abq";
if(my_strcmp(arr1,arr2)>0)
{
printf(">\n");
}
else if(my_strcmp(arr1,arr2)==0)
{
printf("=\n");
}
else
{
printf("<\n");
}
return 0;
}
strcpy,strcat,strcmp都是长度不受限制的字符串函数
strncpy,strncat,strncmp都是长度受限制的字符串函数
int main()
{
char arr1[20]="****************";
char arr2[]="abcd";
strncpy(arr1,arr2,3);
printf("%s\n",arr1);//结果是abc*************
return 0;
}
注意:
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标后面追加0,直到num个
int main()
{
char arr1[20]="abc\0*****";
char arr2[]="defgh";
strncat(arr1,arr2,3);//会补一个\0
printf("%s\n",arr1); //打印结果是"abcdef"(f后有\0)
return 0;
}
int main()
{
char1[]="abcdef";
char2[]="abcdqw";
int ret = strncmp(arr1,arr2,4);
//前四个字符arr1小于arr2的值,返回小于0的数字
printf("%d\n",ret);
return 0;
}
定义:
strstr会返回str1中str2第一次出现的位置
如果str1中没有str2,就返回NULL
int main()
{
char arr1[]="abcdefghi";
char arr2[]="def"
char* ret= strstr(arr1,arr2);
if(ret==NULL)
{
printf("找不到\n");
}
else
{
printf("%s\n",ret);//打印结果是defghi
}
return 0;
}
必须引入一个cp临时指针
记录字符开始匹配的位置
再引入两个指针s1,s2
遍历str1,str2指向的字符串
my_strstr(const char* str1,const char* str2)
{ const char* cp;
const char* s1;
const char* s2;
assert(str1 && atr2);
if(*str2=='\0')
return str1;
cp =str1;
while(*cp)
{
s1 = cp;
s2 = str2;
while(*s1 && *s2&& *s1==*s2)//可能有多个相等的字符,不能用if语句
{
s1++;
s2++;
}
if(*s2=='\0')
return cp;
cp++;
}
return NULL;
}
int main()
{
char arr1[]="abcddddefghi";
char arr2[]="def"
char* ret= my_strstr(arr1,arr2);
if(ret==NULL)
{
printf("找不到\n");
}
else
{
printf("%s\n",ret);//打印结果是defghi
}
return 0;
}
1.写代码要考虑全面
2.善于画图辅助理解才可!
用于切割字符串,有记忆属性!
比如:
sep参数是一个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含0个或者多个由sep字符串中的一个或者多个分隔符分割的标记
strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok会改变被操作的字符串,所以在使用strtok函数切分字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,str将保存它在字符串中的位置。
strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回NULL指针。
int main()
{
char arr1[] ="[email protected]";
char arr2[] ="192.168.101.23 "
char buf1[200] = {0};
char buf2[200] = {0};
strcpy(buf1,arr1);
//识别到@的位置并记住,返回s的地址
strcpy(buf2,arr2);
char* p="@.";
char* s=NULL;
//常用的打印方式----for循环
for(s=strtok(buf1,p);s!=NULL;strtok(NULL,p) )
{
printf("%s\n",s);
}//结果为shijiaqing
// yeah
// net
for(s=strtok(buf2,p);s!=NULL;strtok(NULL,p) )
{
printf("%s\n",s);
}//结果为192
// 168
// 101
// 23
return 0;
}
定义:
char* strerror (int errnum);
返回错误码所对应的错误信息
是将错误码翻译成错误信息,返回错误信息的字符串的起始地址!
不管是使用库函数,还是进行正规软件设计都会涉及错误码
404就是一个典型的错误码,访问失败
C语言中如果发生错误,就会将错误码放在errno的变量中
errno是一个全局变量,可以直接使用
int main()
{
int i =0;
for(i=0;i<10;i++)
{
printf("%d:%s\n",i,strerror(i));
}
return 0;
}
结果如下:
//打开文件的例子
//fopen 以读的形式打开文件
//如果文件存在,打开成功
//如果文件不存在,打开失败
int main()
{
FILE* pf = fopen("add.test","r");
if(pf==NULL)
{
printf("打开文件失败,原因是:%s\n",strerror(errno));
return 1;
}
else
{
printf("打开文件成功\n");
}
return 0;
}
直接打印错误码所对应的错误信息
perror = printf + strerror
定义:
void perror(const char* str)
int main()
{
FILE* pf = fopen("add.test","r");
if(pf==NULL)
{
perror("打开文件失败");
return 1;
}
else
{
printf("打开文件成功\n");
}
return 0;
结果如下:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------