一.字符串函数有以下的分类
strlen 统计字符串长度
strcmp 字符串比较
strcpy 字符串复制
strcat 字符串追加
strncmp、strncpy、strncat
strstr字符串查找
strtok 字符串分割
strerror 错误信息报告
二.字符串函数详解
1.strlen
size_t strlen (const char *str);
strlen的作用是统计字符串的长度,本质是统计\0之前的字符个数,如果字符串中没有\0则会返回一个随机值
注意:strlen返回的类型是size_t,这导致如果想用strlen的返回值比较大小时,被比较的另一个数也会转成size_t类型
如下
#include<stdio.h>
#include<string.h>
int main()
{
if (strlen("hello" )> -1)
printf(">");
else if (strlen("hello") < -1)
printf("<");
return 0;
}

这里的结果是<,这是就是因为strlen的size_t,在比较大小时候,-1也会转换成size_t的类型,而-1在内存中的存储的补码32位全为1,将他看成无符号数就是一个非常大的整数,所以是<
strlen的模拟实现的三种方式:
//指针实现
#include<stdio.h>
#include<assert.h>
int my_strlen(char* str)
{
assert(str);
char* start = str;
while (*str++ != '\0');
return str - start - 1;
}
int main()
{
char str[] = "hello";
int ret = my_strlen(str);
printf("%d", ret);
return 0;
}
//计数器实现
#include<stdio.h>
#include<assert.h>
int my_strlen(char* str)
{
assert(str);
int count = 0;
while (*str++ != '\0')
{
count++;
}
return count;
}
int main()
{
char str[] = "hello";
int ret = my_strlen(str);
printf("%d", ret);
return 0;
}
//递归实现
#include<stdio.h>
#include<assert.h>
int my_strlen(char* str)
{
assert(str);
if (*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char str[] = "hello";
int ret = my_strlen(str);
printf("%d", ret);
return 0;
}
2.strcmp
int strcmp(const char* str1,const char* str2)
标准规定:
str1>str2,则返回大于0的数字,str1=str2,则返回0,str1<str2,则返回小于0的数字
判断标准:
从左到右依次对应取出str1和str2的字符进行ASCII码值的比较
strcmp的模拟实现:
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1&&str2);
while (*str1 == *str2)
{
if (*str1 == '\0' && *str2 == '\0')
return 0;
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
else
return -1;
}
int main()
{
char str1[] = "abcd";
char str2[] = "abcd";
int ret = my_strcmp(str1, str2);
printf("%d", ret);
return 0;
}
3.strcpy
char* strcpy(char* dest,const char* src)
strcpy可以将源字符串的内容拷贝到目标字符串内
注意:源字符串必须以\0结尾
strcpy会将源字符串的\0一并拷贝到目标字符串中
目标字符串的空间必须大于或者等于源字符串的空间
目标字符串必须可变
strcpy的模拟实现:
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest && src);
while (*dest++ = *src++);
return ret;
}
int main()
{
char str1[10] = { 0 };
char str2[] = "hello";
my_strcpy(str1, str2);
printf("%s", str1);
return 0;
}
4.strcat
char* strcat(char* dest,const char* src)
strcat可以将源字符串追加到目标字符串后
注意:源字符串与目标字符串必须以\0结尾
目标字符串的空间必须足够大,且可以修改
strcat的模拟实现:
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest != '\0')
dest++;
while (*dest++ = *src++);
return ret;
}
int main()
{
char str1[20] = "hello ";
char str2[] = "world";
my_strcat(str1, str2);
printf("%s", str1);
return 0;
}
5.strncpy、strncmp、strncat
char * strncpy ( char * destination, const char * source, size_t num );
char * strncat ( char * destination, const char * source, size_t num );
int strncmp ( const char * str1, const char * str2, size_t num );
功能与之前的函数一致,不过可以控制个数
6.strstr
char* strstr(const char* str1,const char* str2)
strstr可以查找str2指向的字符串是否为str1指向字符串的子串,若是,则返回str1指向字符串出现str2指向字符串的起始位置
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
char* cp = (char*)str1;
while (*cp)
{
char* cur1 = cp;
char* cur2 = (char*)str2;
while (*cur1 == *cur2&&cur1&&cur2)
{
cur1++;
cur2++;
}
if (*cur2 == '\0')
return cp;
cp++;
}
return NULL;
}
int main()
{
char str1[] = "abcde";
char str2[] = "cd";
char*ret=my_strstr(str1, str2);
printf("%s", ret);
return 0;
}
7.strtok
char* strtok(char* str,const char* sep)
sep是一个字符串,存储了用作分隔符的字符的集合
str指定一个字符串,其中含有sep中的一个或多个分隔符
如果传入的str不为NULL,strtok会找到第一个分隔符将它替换为\0,并返回这个分隔符前的第一个字符的地址
若传入的str为NULL,strtok会从上一次找到分隔符的位置开始,找到下一个分隔符,并将它替换为\0,并返回这个分隔符前的第一个字符的地址
若找不到下一个标记,则返回NULL
参考代码如下:
#include <stdio.h>
int main()
{
char* p = "1398421180@qq.com";
const char sep[] = "@.";
char arr[50] = { 0 };
strcpy(arr, p);//将数据拷贝一份处理
char* str = NULL;
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
{
printf("%s",str);
}
return 0;
}
8.strerror
char* strerror(int errnum)
errno是记录系统最后一次错误的代码,将他传入strerror中可以返回错误信息的地址,并打印出错误信息
参考代码如下
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main ()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n",strerror(errno));
//errno: Last error number
return 0;
}