一、函数strlen ,strcmp ,strcpy ,strcat的模拟实现
- 求字符串长度 strlen
strlen 这个函数是用来求字符串长度的,如果我们要自己动手去实现这个函数,要知道的一点是,这个函数统计的是 \0 之前的字符个数,它的返回值是无符号整型,所以下面的这种写法不可取。
如果直接作差会产生一个负数,但是如果是无符号整数来表示就是一个大于0的数,所以就会输出错误的结果,如果非要作差,那我们需要把strlen的返回值强转为整型。
int main()
{
size_t n = strlen("abc") - strlen("abcdef");
if (n > 0)
{
printf("大于");
}
else
{
printf("小于");
}
return 0;
}
这里说明一点,如果我们只是比较或者遍历字符串,不改变它的值,那我们可以在写函数参数的时候用const修饰,就不会出现不小心改变它的值的情况,安全性更高。
//strlen的表示格式:size_t strlen ( const char * str );
//模拟实现strlen函数:
size_t my_strlen( const char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
size_t n = my_strlen("abcd");
printf("%u\n", n);//注意打印时是%u
return 0;
}
- strcmp,这个函数是用来比较两个字符串的,它会挨个比较,实则比的是每个字符的ASCII码值,如果第一个字符串大于第二个字符串会返回大于0的数,小于会返回小于0的数,如果两个字符串相等会返回0。
举例说明:比如"abc" 和 “abq” ,当比到第三个字符的时候,q的ASCII码值大于c的ASCII码值,所以会返回大于0的数。
我们可以自己动手来实现一下
//strcmp的使用格式:
//int strcmp ( const char * str1, const char * str2 );
//自己实现strcmp
int my_strcmp(const char* str1, const char* str2)
{
while (*str1 == *str2)
{
if (str1 == '\0')//每次进来之前先判断一下字符串是否已经结束了
{
return 0;//如果已经结束了,那说明两个字符串相等,直接返回0
}
str1++;//否则指针就继续往后走
str2++;
}
if (str1 > str2)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "abcq";
int n = my_strcmp(arr1, arr2);
printf("%d\n", n);
return 0;
}
3.函数 strcpy,这个函数可以把一个字符数组的内容拷贝到另一个字符数组中,它有两个参数,第一个参数是目的地址,第二个参数是源地址,也就是把源地址的数据拷贝到目的地址中,然后它的返回值是char* 的指针,返回的是目的地 的地址。
这里还需要注意下的是,什么时候拷贝停止呢,就是遇到\0的时候,说明字符串已经结束了,拷贝就会停止,所以我们提供的源字符串中一定要保证有\0.
//strcmp的使用格式:
//char * strcpy ( char * destination, const char * source );
//自己模拟实现函数strcpy:
char* my_strcpy( char* dest, const char* src)
{
//这里是为了记录目的地的初始地址,因为后面指针偏移到后面的位置
char* ret = dest;
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;//将src中的\0也拷贝过去
return ret;
}
int main()
{
char arr1[20] = "hello world";
char arr2[] = "xxxxx";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
- strcat ,这个函数是用来连接两个字符串的,它也有两个参数,第一个参数是目的地址,第二个参数是源地址,也就是在目的地址数据的后面追加源地址的数据。所以第一步,我们要找到目的地址数据结束的位置,也就是有\0的位置,所以在使用这个函数时,我们一定要保证自己提供的目的字符串中有\0.它返回的还是目的地 的地址。
//strcat的使用格式:
//char * strcat ( char * destination, const char * source );
//自己模拟实现函数strcat:
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
//找到目的字符串结束的位置
while (*dest!='\0')
{
dest++;
}
while (*src!='\0')
{
*dest = *src;//将src中的数据放到dest中
dest++;
src++;
}
return ret;
}
int main()
{
char arr1[20] = "hello ";//要保证arr1的空间足够且可变
char arr2[] = "world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
二、函数strncmp ,strncpy ,strncat
上面的这几个函数都是长度不受限制的函数,但是它们比较关注 \0 的存在,下面介绍的这几个跟上面类似的函数是长度受限的函数,但是它们不受 \0 的限制。如果要比较的话,这几个函数在使用时其实更加安全。
它们的使用格式如下
int strncmp ( const char * str1, const char * str2, size_t num );
//只比较前num个字符,其余的跟strcmp函数没什么区别
char * strncpy ( char * destination, const char * source, size_t num );
//只拷贝前num个字符,如果源地址的字符串不够拷贝就拿\0来凑
char * strncat ( char * destination, const char * source, size_t num );
//只追加前num个字符,如果源地址的字符串不够,把源字符串拷贝完就行了,不添加其他字符