目录
一.strlen函数
1.函数简介
strlen所作的是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值(长度不包含'\0')。
原型声明:extern unsinfned int strlen(char *s);
头文件:#include <string.h> 和 #include <stdio.h>。
功能:计算给定字符串的(unsigned int型)长度,不包括'\0'在内。
说明:返回s的长度,不包括结束符NULL。
2.模拟代码
什么是断言:
断言概念:编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言,而在部署时禁用断言。
用法:void assert(int test);
头文件:#include<assert.h>
作用:如果它的条件返回错误,则终止程序执行
注意:assert是宏,而不是函数。
#include<stdio.h>
#include<string.h>
#include<assert.h>
int mystrlen(char *str){
assert((str != NULL));//断言
int count = 0;//计数器,记录字符串长度
while (*str != '\0'){
str++;
count++;
}
return count;
}
void main(){
char str[10] = "ajfwiwegd";
printf("%d\n", mystrlen(str));
printf("%d\n", strlen(str));
}
3.对比截图
二.strcpy函数
1.函数简介
将后一字符串复制到前一字符串的空间。
原型声明:char *strcpy(char* dest, const char *src);
头文件:#include <string.h> 和 #include <stdio.h>。
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
2.模拟代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
char *mystrcpy(char *dest, const char *src){
assert((dest != NULL) && (src != NULL));//断言
char *tmp = dest;//保存dest的起始地址,用于返回
while (*src != '\0'){
*dest = *src;
src++;
dest++;
}
*dest = '\0';
return tmp;
}
void main(){
char src[10] = "ajfwiwegd";
char dest[20] = { 0 };
printf("%s\n", mystrcpy(dest,src));
printf("%s\n", strcpy(dest,src));
}
3.对比截图
4.注意
一定要设置一个指针tmp用于保存dest的起始地址,而不能直接返回dest,因为此时dest已经指向字符串末尾,而不是起始位置。模拟strcat函数时也要注意这个问题。
三.strncpy函数
1.函数简介
原型声明:char *strncpy(char *dest, const char *src, int n);
参数:
- dest:表示复制的目标字符数组;
- src:表示复制的源字符数组;
- n:表示复制的字符串长度。
头文件:#include <string.h> 和 #include <stdio.h>。
功能:把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。
说明:
与strcpy的区别:
1.strcpy只是复制字符串,但不限制复制的数量,很容易造成缓冲溢出。strncpy要安全一些。
2.strncpy能够选择一段字符输出,strcpy则不能。
2.模拟代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
char *mystrncpy(char *dest, const char *src,int n){
assert((dest != NULL) && (src != NULL));//断言
char *tmp = dest;//保存dest的起始地址,用于返回
for (int i = 0; i < n; i++){
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return tmp;
}
void main(){
char dest[100] = { 0 };
char src[] = "fghfafig";
printf("%s\n", mystrncpy(dest,src,5));
printf("%s\n", strncpy(dest,src,5));
}
3.对比截图
四.strcmp函数
1.函数简介
字符串逐字符比较大小。
原型声明:strcmp(const char *s1,const char * s2);
头文件:#include <string.h> 和 #include <stdio.h>。
功能:strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。
基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。
说明:这里面只能比较字符串,即可用于比较两个字符串常量,或比较数组和字符串常量,不能比较数字等其他形式的参数。
2.模拟代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
int mystrcmp(const char *s1, const char *s2){
assert((s1 != NULL) && (s2 != NULL));//断言
int ret = 0;
while (*s1 != '\0' || *s2 != '\0')//只需任一字符串未到结尾
{
ret = *s1 - *s2;
if (ret != 0){
break;
}
s1++;
s2++;
}
return ret;
}
void main(){
char s1[] = "abcde";
char s2[] = "fghijk";
printf("%d\n", mystrcmp(s1,s2));
printf("%d\n", strcmp(s1,s2));
}
3.对比截图
五.strcat函数
1.函数简介
将两个字符串进行连接。
原型声明:extern char *strcat(char *dest, const char *src);
头文件:#include <string.h> 和 #include <stdio.h>。
功能:把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除*dest原来末尾的“\0”)。要保证*dest足够长,以容纳被复制进来的*src。*src中原有的字符不变。返回指向dest的指针。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
2.模拟代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
char *mystrcat(char *dest, const char *src){
assert((dest != NULL) && (src != NULL));//断言
char *tmp = dest;//保存dest的起始地址,用于返回
while(*dest != '\0'){//到dest的末尾
dest++;
}
while (*src != '\0'){//从src的起始接到dest的末尾
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return tmp;
}
void main(){
char dest[20] = "abcde";
char src[] = "fghijk";
printf("%s\n", mystrcat(dest,src));
//printf("%s\n", strcat(dest,src));//和标准的对比
}
3.对比截图
(1).自定义的mystrcat函数
(2).标准库中strcat函数
六.strncat函数
1.函数简介
原型声明:char * strncat(char *dest, const char *src, size_t n);
头文件:#include <string.h> 和 #include <stdio.h>。
功能:把src所指字符串的前n个字符添加到dest所指字符串的结尾处,并覆盖dest所指字符串结尾的'\0',从而实现字符串的连接。
说明:src和dest所指内存区域不可以重叠,并且dest必须有足够的空间来容纳src的字符串。
2.模拟代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
char *mystrncat(char *dest, const char *src,int n){
assert((dest != NULL) && (src != NULL));//断言
char *tmp = dest;//保存dest的起始地址,用于返回
while (*dest != '\0'){//到dest的末尾
dest++;
}
for (int i = 0; i < n; i++){
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return tmp;
}
void main(){
char dest[100] = { 'a', 'b', 'c' };
char src[] = "fg";
printf("%s\n", mystrncat(dest,src,2));
//printf("%s\n", strncat(dest,src,2));
}
3.对比截图
(1).自定义的mystrncat函数
(2).标准库中strncat函数
七.strstr函数
1.函数简介
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL。
原型声明:string strstr( string1,string2);
头文件:#include <string.h> 和 #include <stdio.h>。
功能:strstr返回一个指针,指向string2在string1中首次出现的位置。
说明:寻找某字符串在另一字符串中第一次出现的位置,并返回查找到字符串的位置之后的全部字符串。 详细说明如下:
(1)参数是字符串类型的参数,要传入的是被查找的字符串。
(2)参数二是字符串类型的参数,传入的是要查找的字符串。
(3)strstr函数会寻找参数二在参数中出现的位置,并返回查找到字符串的位置之后的全部字符串。当没有查找到符合的字符串时,strstr函数会返回 FALSE(布尔值)。
(4)注意: strstr函数在查找时,大小写会被认为是不同的字符串。PHP另外提供一个大小写会被视为相同的函数: stristr。
(5)注意:如果只是要査找某字符串是否存在于另一字符串中,则建议使用 strpos这个函数, strpos函数执行的速度会比 strstr快,而且使用更少的内存。
2.模拟代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
char *mystrstr(char *s1, char *s2){
assert((s1 != NULL) && (s2 != NULL));//断言
char *tmp = NULL;
int flag = 0;//标记上一个字符是否相同
while (*s2!='\0'){
if (*s1 != *s2){
tmp = NULL;
flag = 0;
}
if (*s1 == *s2){
if (flag == 0){//上一个字符不同,记录起始位置
tmp = s1;
}
flag = 1;//防止起始位置改变
s2++;
}
s1++;
}
return tmp;
}
void main(){
char s1[] = "abcdefghijk";
char s2[] = "fgh";
printf("%s\n", mystrstr(s1,s2));
printf("%s\n", strstr(s1,s2));
}
3.对比截图
4.注意
这种方法必须要把if (*s1 != *s2)的判断条件写在if (*s1 == *s2)之前。因为如果*s1==*s2,其中s2++,这时会继续满足判断 if (*s1 != *s2)的条件,从而产生错误结果。
八.atoi函数
1.函数简介
原型声明:int atoi(const char *nptr);
头文件:#include <stdlib.h> 和 #include <stdio.h>。
功能:扫描参数 nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0。
说明:该函数要求被转换的字符串是按十进制数理解的。atoi输入的字符串对应数字存在大小限制(与int类型大小有关),若其过大可能报错-1。
2.模拟代码
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<limits.h> //使用 INT_MAX、INT_MIN 判断是否超出整形范围
int myatoi(const char *nptr){
assert(nptr != NULL);
if (*nptr == '\0'){//如果字符串长度为0
return 0;
}
while (*nptr == ' '){//如果字符串前面有很多空格
nptr++;
}
int flag = 1;
if (*nptr == '-'){//判断是正数还是负数
flag = -1;
nptr++;
}
int n = 0;
while (*nptr != '\0'){
if ((*nptr <= '0') || (*nptr >= '9')){//判断是否为十进制数字符,也可以用isdigit函数判断
break;//不是 退出循环
}
n = n * 10 + flag*((int)*nptr - '0');
if (n < INT_MIN || n>INT_MAX){//超出整形范围
return -1;
}
nptr++;
}
return (int)n;
}
void main(){
char str[] = " -1426a432";
printf("%d\n", myatoi(str));
printf("%d\n", atoi(str));
}
3.对比截图
4.注意
注意该函数的一些特殊情况和如何将字符串转换为数字的方法。
如有建议或想法,欢迎一起讨论学习~