1.实现strlen
sizt_t strlen (const char *str1);//定义如此
函数返回值是一个无符号整形数据,参数类型是一个字符指针。
代码实现如下:
size_t my_strlen(char const *str1)
{
size_t count = 0;
while (*str1++)
{
count++;
}
return count;
}
int main()
{
char str[] = "1234567";
printf("%u",my_strlen(str));
return 0;
}
2.实现strcpy
查阅msdn知道strcpy的函数声明形式如下
char *strcpy( char *strDestination, const char *strSource )
基本用法如下
将字符数组arr2(源操作数)中的字符复制到arr1(目的操作数)中。
void my_strcpy(char* dest, char* ser)
{
//字符串复制
while (*dest++ = *ser++)
{
;
}
}
int main()
{
char arr1[20] = "***********";
char arr2[] = "student";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
while (*dest++ = *ser++)
·1:后置++的表达式,先使用变量,后对变量进行自增。
2:直接在while循环中进行赋值,因为每一个字符串在定义时,系统会默认加上一个‘\0’(字符串结束标志)而'\0'的ascll码值是0,所以当这个赋值操作进行到‘\0’时,*dest先被赋值为\0,然后while循环判断结果,因其结果为0,所以判断为假跳出循环。而前面的字符串的ascll码值都不为0,那就都判断为真,循环继续。
当然我们也要防止函数传参时传了一个空指针。所以在复制前可以加上assert函数(断言函数)
断言函数,中间操作数是指针变量本身,不是解引用后所指向的变量。
如果传参时传过来的参数为NULL,那么系统会报错,编译不能通过。并且会提醒错误位置
再来比较msdn中定义的标准形式 char *strcpy( char *strDestination, const char *strSource )
在源操作数前有一个const关键字,修饰常变量,被他修饰后,变量中的数据不能通过const修饰过的变量名进行改变(但可以通过指针来改变变量中的数据)这里用来防止字符串赋值时,源操作数和目的操作数写反(会导致结果不能达到预期)
现在 唯一不同的就是函数的返回类型,msdn中strcpy函数返回类型是char * 一个指向字符类型的指针(就是源操作数的首地址)
printf("%s\n", my_strcpy(arr1, arr2));//函数的链式访问,
一个函数的返回值,作为另一个函数的一个操作数。
所以要进行链式访问,那么该函数必须要有返回值。(函数的返回类型不能为void)
下面就是my_strcpy函数的完整实现
char* my_strcpy(char* dest, const char* ser)
{
//字符串复制
assert(dest != NULL);//断言
//用法和if相同,不满足就会报错
assert(ser != NULL);
char* ch = dest;
while (*dest++ = *ser++)
{
;
}
return ch;
}
int main()
{
char arr1[20] = "***********";
char arr2[] = "student";
printf("%s\n", my_strcpy(arr1, arr2));//函数的链式访问
return 0;
}
3:stscat
char *strcat( char *strDestination, const char *strSource )
通过调试的方法可知strcat的功能,然后编写程序进行实现。
功能:字符串追加函数,在目的操作数最后追加上源操作数
//实现strcat
#include<stdio.h>
#include<assert.h>
//char *strcat( char *strDestination, const char *strSource )
char* my_strcat(char* dest,char* str )
{
assert(dest);//断言函数
assert(str);//传参时二者都不能为空指针
char* ch = dest;
while (*dest++ != '\0')
{//数到指针指向第一个为\0的字符
;
}//此时*dest指向第一个‘\0’的后一个位置。
dest--;
while (*dest++ = *str++)
{
;
}
return ch;
}
int main()
{
char arr1[20] = "hello ";
char arr2[] = "world";
printf("%s", my_strcat(arr1, arr2));
return 0;
}
4:strstr
char *strstr( const char *string, const char *strCharSet )
功能如下:
查询源操作数的字符串在目的操作数的位置,查询成功返回源操作数所在位置的地址,查询不到则返回NULL.
#include<stdio.h>
#include<string.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
int count = 0;
char* s2 = str2;
while (1)//
{
while (*str1 != *str2 && str1 != 0)
{//加第二个条件防止str1越界
str1++;
}
char* s1 = str1;//记录第一个相同字符的位置。
while ( (*str1 == *str2)&&*str1 && *str2 )
{//计数,记录从第一个相同字符开始
//后面相同字符的个数
//在进行比较时,++或者--不要放在while条件中
//在赋值时可以。
str1++;
str2++;
}
if (*str2 == 0)
{//如果记录的字符相同的个数和str2中
//字符个数相同,返回此时str1中第一个相同字符的地址
return s1;
}
else
{//否则就让str2回到第一个字符的位置重新开始比较
//并且让str1回到刚才第一个相同字符的后面一个位置。
str2 = s2;
str1 = s1 + 1;
}
count = 0;
if (*str1 == 0)
{
return NULL;
}
}
}
int main()
{
char arr1[] = "abbbbbcjias";
char arr2[] = "bbbc";
char *s = my_strstr(arr1, arr2);
if (s == NULL)
{
printf("没找到 \n");
}
else
{
printf("找到了 %s\n",s);
}
return 0;
}
5:strcmp
定义如下: int strcmp( const char *string1, const char *string2 );
功能,比较两串字符串,相同返回0,*string>*string2返回1 *string<*string2返回-1.
要特别注意:在对两字符串进行比较时,是两字符串的每一个对应位的字进字符行比较,于字符串本身的长度无关。
#include<stdio.h>
#include<assert.h>
#include<string.h>
int my_strcmp(const char* string1, const char* string2)
{
//断言函数
assert(string1);
assert(string2);
while (*string1)
{
if ((*string1 == *string2 ) && *string1 != 0 && *string2 != 0)
{
string1++;
string2++;
}
if (*string1 > *string2)
{
return 1;
}
if (*string1 < *string2)
{
return -1;
}
}
return 0;
}
int main()
{
while (1)
{
char ch[20] = { 0 };
char ch1[20] = { 0 };
gets(ch);
gets(ch1);
//int a = strcmp(ch, ch1);
printf("%d\n", my_strcmp(ch, ch1));
printf("%d\n", strcmp(ch, ch1));
}
return 0;
}