1 strlen函数
原型:
size_t strlen(const char* string)
功能:
字符串都以'\0'作为结束标志,strlen会返回字符串中'\0'前面出现的字符个数.
注意事项:
I 指向的字符串必须以'\0'结尾.
II 函数返回值类型是size_t.[可考虑强制类型转换]
实现方法:
A 计数器方法
即遍历字符串,直到找到'\0'停止计数.
size_t my_strlen(const char* arr)
{
assert(arr);//断言不为空指针
size_t num = 0;//统计数目
while (*arr)//*arr是否为'\0'
{
num++;
arr++;
}
return num;
}
B 递归方法
例如:
strlen("abc") = 1 + strlen("bc").
size_t my_strlen(const char* arr)
{
assert(arr);//断言不为空指针
if(*arr == '\0')
return 0;
else
return 1+my_strlen(arr+1);
}
C 指针 - 指针方法
(同一数组中的)两个指针相减可得到它们之间的元素个数.
size_t my_strlen3(const char* arr)
{
assert(arr);//断言不为空指针
const char* init = arr;//保留arr的初始值
while (*arr)//使arr指向'\0'
{
arr++;
}
size_t num = arr - init;//两个指针相减得到它们之间的元素个数
return num;
}
2 strcpy函数
原型:
char* strcpy(char* strDestination, const char* strSource)
功能:
将源字符串的内容拷贝给目标字符串,拷贝的内容将覆盖目标字符串相应位置的内容,并返回目标字符串首字符的地址.
拷贝前:
拷贝后:
注意事项:
I 会将源字符串的'\0'拷贝到目标空间.
II 目标空间必须足够大,以确保能存放源字符串.
III 目标空间必须可变.(目标字符串不能是常量字符串)
实现方法:
遍历源字符串的同时,把源字符串的内容赋给目标字符串,赋值到源字符串的'\0'为止.
char* my_strcpy(char* dest, const char* source)
{
assert(dest && source);//断言皆不为空指针
char* re = dest; //函数最后返回目标字符串首地址
while (*dest++ = *source++)//先把source指向的字符赋给dest指向位置,再使它们的指向位置向后一位,
{ //直到把'\0'赋给*dest时,表达式整体的值为0,跳出循环
;
}
return re;
}
3 strcat函数
原型:
char* strcat(char* strDestination, const char* strSource)
功能:
将源字符串内容追加到目标字符串末尾,并返回目标字符串的首字符地址
追加前:
追加后:
注意事项:
I 也会把源字符串的'\0'追加到目标字符串尾部,以上的dest[11]没有变红是因为原来也是'\0'.
II 目标空间要足够大.
III 目标空间必须可修改(不能指向常量字符串).
实现方法:
找到目标字符串的'\0',然后在遍历源字符串的同时,把内容赋给目标字符串,直到赋值到'\0'
(从目标字符串的'\0'开始赋值)
char* my_strcat(char* dest, const char* source)
{
assert(dest && source);//断言都不是空指针
char* re = dest; //记住目标字符串的首位置
while (*dest != '\0') //使dest指向'\0'
{
dest++;
}
while (*dest++ = *source++)//把源字符串的内容赋给目标字符串尾部
{ //每次赋给一个字符,地址向后移动一位
; //当找到源字符串的'\0'时,先把它赋给目标字符串,再退出循环
}
return re;
}
4 strcmp函数
原型:
int strcmp(const char* string1, const char* string2)
功能:
比较两个字符串从左到右对应位置上的字符大小(ASCII码值).
str1 > str2 返回大于0的数字;
str1 < str2 返回小于0的数字;
str1 == str2 返回0.
实现方法:
int my_strcmp(const char* arr1, const char* arr2)
{
assert(arr1 && arr2);
//从左到右依次比较字符串相应位置的字符大小, 直到*arr1!=*arr2或同时为'\0'
while (*arr1 == *arr2)
{
if (*arr1 == '\0')//说明两字符串相同
{
return 0;
}
arr1++;//比较下一对
arr2++;
}
//一旦有一次不相等
if (*arr1 > *arr2)
return 1;
else
return -1;
}
5 strncpy函数
原型:
char* strncpy(char* strDest, const char* strSource, size_t count)
功能:
将源字符串的count个字节拷贝到目标字符串的相应位置,比strcpy多了一层思考,返回目标字符串首元素地址.
注意事项:
I 目标字符串一定要足够大
II 若源字符串的字符个数小于count,拷贝的字符会拿'\0'填充,阴间案例如下
拷贝前:
拷贝后:
实现方法:
char* my_strncpy(char* destination,const char* source, size_t count)
{
//(从左到右)从源字符串中拷贝count个字节(字符)到目标字符串相应位置
assert(destination && source);
char* re = destination;
for (int i = 0; i < count; i++)
{
//要拷贝count次
if (*source == '\0')//如果已经拷贝到源字符串末尾,那就用'\0'填充
{
*destination = '\0';
destination++;
}
else//正常拷贝
{
*destination = *source;
destination++;
source++;
}
}
return re;
}
6 strncat函数
原型:
char* strncat(char* strDest, const char* strSource, size_t count)
功能:
将源字符串的count个字符/字节(因为一个字符的大小就是1byte)追加到目标字符串第一个'\0'处.
注意事项:
I 追加完count个字符后,会自动再添加一个'\0'.
追加前:
追加后:
II 源字符串的字符不够count个,不会进行填充.
III 若源字符串的第count个字符本身就是'\0',不会自动去添加'\0'.
追加前:
追加后:
实现方法:
char* my_strncat(char* destination, char* source, size_t num)
{
assert(destination && source);
//将源字符串的num个字符追加到目标字符串第一个'\0'处
//若源字符串追加完则停止
char* re = destination;//保存目标字符串初始值
while (*destination)//使*destination找到'\0'
{
destination++;
}
//开始追加
for (int i = 0; i < num; i++)
{
//追加num个字符
if (*source != '\0')//正常追加
{
*destination = *source;
destination++;
source++;
}
else if(*source == '\0')//源字符串已经全部追加完了
{
*destination = *source;
return re;//直接结束函数
}
}
//追加的num个字符都没有'\0'
*destination = '\0';//末尾自动添加'\0'
return re;
}
7 strncmp函数
原型:
int strncmp(const char* string1, const char* string2, size_t count)
功能:
从左向右比较,只比较两字符串对应位置的前count个字符,返回值规则和strcmp一样。
实现方法:
int my_strncmp(char* str1, char* str2, size_t num)
{
assert(str1 && str2);
for (int i = 0; i < num; i++)
{
//比较num对
if (*str1 == *str2)//如果相同比较下一对
{
str1++;
str2++;
}
else if (*str1 > *str2)//一旦有一对不同函数就可以返回结束
{
return 1;
}
else
{
return -1;
}
}
//比较完num对后都是相等的
return 0;
}
8 strstr函数
原型:
char* strstr(const char* string, const char* strCharSet)
功能:
看strCharSet指向的字符串是否是string的子串,就是在一个字符串里找另一个字符串.
如果是,则返回子串第一次出现在string中的位置,否则返回NULL.
实现方法:
//思路:定义2个指针p2,p1分别指向 要查找的子串 和 源字符串 首元素
// 定义1个指针record负责指向开始对照的位置
//当*p1!=*p2时,record++, p1++
//当*p1 == *p2时,record不变,p1++,p2++,逐个对照,
//直到p2指向'\0'(要查找的子串找到了)或者*p1!=*p2(没找到该子串)
char* my_strstr(const char* source, const char* search)
{
assert(source && search);
const char* p1 = source;
const char* p2 = search;
const char* record = p1;//记录当前开始对照的位置
while (*record != '\0')//若*record == '\0',说明源字符串中找不到字串
{
//p1和record一开始都指向开始对照的位置,但p1之后要用来与p2指向的元素逐个对照
p1 = record;
while (*p1 == *p2 && *p2)//*p2为'\0'时已经找到了 ///////
{
p1++;
p2++;
}
if (*p2 == '\0')//对照完成后子串的p2指向'\0',说明找到了,返回开始对照的位置record
return record;
//如果没找到,p2要重新指向子串的首字符
p2 = search;
//同时下一次开始对照的位置+1
record++;
}
return NULL;
}
9 strtok函数
原型:
char* strtok(char* strToken, const char* strDelimit)
功能:
在str中找到sep中的符号,并用'\0'结尾,并返回这次分割开的字段的首字符地址.
例如:
具体使用方法
A
strtok的第一个参数不为NULL,函数会找到str中的第一个分隔符标记,并保存这个分割符的位置,返回这次分割开的字段的首字符地址.
strtok的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,继续往后查找下一个标记.并返回这次分割开的字段的首字符地址.例:
B 若字符串中不存在更多标记,返回NULL.
那如何做到不管原字符串里有多少个分割符,都能一次性打印全部分开的字符串呢?
注意事项:
I strtok会改变被操作的字符串,所以最好临时拷贝一份,来使用该函数.(此时可使用strcpy/strcnpy)
II 这两个参数指向的是字符串首元素地址,都要以'\0'结尾.
10 strerror函数
在库函数调用失败时,会留下一个错误码error,它是一个全局变量,一开始默认是0
原型:
char* strerror(int errnum)
功能:
返回错误码所对应的错误信息.//每个错误码都对应一个错误信息
例: