- 求字符串长度
- strlen
- 长度不受限制的字符串函数
- strcpy
- strcat
- strcmp
- 长度受限制的字符串函数介绍
- strncpy
- strncat
- strncmp
- 字符串查找
- strstr
- strtok
- 错误信息报告
- strerror
- 字符 *** 作
- 内存 *** 作函数
- memcpy
- memmove
- memset
- memcmp
strlen
strlen 计算字符串’\0’之前的个数,只适用于字符串。
- 字符串已 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
含 ‘\0’ )。 - 参数指向的字符串必须要以 ‘
- 注意函数的返回值为size_t,是无符号的( 易错 ) ’ 结束。#
size_t是无符号整型(unsigned int)在C语言库中的重定义
练习
includeint
main ()const
{
char *=str1 "abcdef" ;const
char *=str2 "bbb" ;if
(strlen()str2-strlen()str10>)printf
{
()"str2>str1\n";}
else
printf
{
()"srt1>str2\n";}
return
0 ;} size_t
解释一下
输出结果:str2>str1,因为strlen的返回类型是size_t,无符号数减无符号数还是无符号数,所以大于0.
模拟实现strlen
循环实现
my_strlen (constchar *) strassert
{
(!=str NULL );size_t
= i 0 ;while
( *++str)++
{
i;}
return
; i}
size_t
递归实现
不能创建临时变量计数器
my_strlen (constchar *) strif
{
( *==str ')' return0
; return(
1 +my_strlen ( +1str ) );}源字符串必须以 ‘ 会将源字符串中的 ‘ 目标空间必须足够大,以确保能存放源字符串。 ’ 拷贝到目标空间。’ 结束。
目标空间必须可变。
长度不受限制的字符串函数
strcpy
strcpy
strcpy字符串拷贝,只适用于字符串。
destination:目的地
source:源
- char*my_strcpy(
证明\0会被拷贝
模拟实现
char* ,constchar* destination) assert (!= sourceNULL
{
);destination assert (!=NULL
);source char *=;
while( p * destination++
= *++destination)//当*source=';'赋给*destination时,这时*destination='//空语句',为假,循环终止,所以这种写法很妙。 }sourcereturn;}
{
源字符串必须以 ‘ 目标空间必须有足够的大,能容纳下源字符串的内容。 ’ 结束。目标空间必须可修改。
char
* pmy_strcat
(
strcat
strcat:
strcat:字符串追加,只适用于字符串。
- char*,
strcat函数不能自己给自己追加。
模拟实现
constchar *)assert( destination!= NULL ); sourceassert
{
(!=destination NULL );char
*=source ; while(*
)++ p ; destination}
while (*destination++
{
destination=*
++
) ;}destinationreturn ; }source第一个字符串大于第二个字符串,则返回大于0的数字 第一个字符串等于第二个字符串,则返回0
{
第一个字符串小于第二个字符串,则返回小于0的数字
int
my_strcmp p(
const
strcmp
strcmp
strcmp:字符串比较函数,只适用于字符串。
C语言标准规定:
- char*,
字符串是如何比较那
模拟实现
两种方法都符合C语言规定。
方法1
const char*) assert( str1!= NULL ); str2assert
{
(!=str1 NULL );while
(*str2 ++ ==*++
) if(str1* == '&&'str2*==
{
')' return0str1 ; } } ifstr2 (**
{
) return1
;
}
else return-str1 > 1str2;
{
} }int
my_strcmp
(
{
const char*,
const
char
方法2
* )assert( !=NULL str1) ; assert( str2!=
{
NULL)str1 ; while(*
++==str2 * ++)if
( *==str1'&&' * ==str2')'return
{
0 ;}str1 } return ( (str2 *)-
{
( *)
)
;
} 拷贝num个字符从源字符串到目标空间。 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个. charstr1* my_strncpy (charstr2*,const
char
长度受限制的字符串函数介绍
strncpy
strncpy
strncpy:拷贝num个字符从源字符串到目标空间,注意strncpy与strcpy不一样,只适用于字符串。
- *,
模拟实现
size_t) assert(!=NULL destination) ; assert( source!=NULL num)
{
;chardestination * =;while
(--source ) if(*
)* p ++ destination=
* ++num;}
{
else *++source=
{
';'destination} } returnsource;}
将源的前 num 个字符追加到目标,外加一个终止空字符。
如果源中 C 字符串的长度小于 num,则仅复制到终止空字符之前的内容。
{
chardestination* my_strncat (char
*
,
const pchar
*
strncat
strncat
strncat:追加指定字符个数,只适用于字符串。
- ,size_t
模拟实现
)assert (!=NULL) destination; assert (!= sourceNULL ) num;
{
char*destination = ;while(
*)source //找到destination的'++'的位置 ;}while
(-- p ) destinationif
(*)destination//判断*source是否为'*',为'++'就不在进去。=
{
destination*++
;
} }num*=
{
';' return;source}比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
{
intdestinationmy_strncmp ( constsourcechar*
,
const
chardestination * ,size_t
) passert
(
strncmp
strncmp
strncmp:比较指定个数的字符串大小,只适用于字符串
- !=
模拟实现
NULL );assert (!= str1NULL ) ;while str2( -- num)
{
if(str1 * !=*)
if(str2 * *)return
1 ;numelsereturn
{
- 1;str1 } ifstr2(
{
* !='||'str1 > *str2!=
')' //如果两个字符相等但是输入超过两个字符串的个数,使字符一直保持相等。++
;
++ ;}}
return
0 ;}str1 char * my_strstr (str2 const char*,
{
str1constchar
str2*)
assert
(
!= NULL)
;
字符串查找
strstr
strstr
strstr:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL,只适用于字符串。
实现原理
图1
图2
图3
模拟实现
assert( !=NULL) ;/* char* p1 = str1;
char* p2 = str2;*/ str1//一般我们把一个类型限制严格的变量,赋给一个类型限制不怎么严格变量时,编译器会报警告。 const char* str2=
{
;conststr1 char *=;
if(str2 * ==')'return
;
while
( *) p1 = str1;
while (* p2 != str2'&&'
* !='&&'str1 ( *==
* str1)
) //一直找到*p2与*p1不相等++str1;
{
p1++ str1;
} if(p1 * == ')' //如果p2='return'证明找完了p2 ; //找到了 } ++;p1 = ;p2}returnNULL
{
p1;//找不到子串
p2}sep参数是个字符串,定义了用作分隔符的字符集合
#
include #includep2 int main()
{
char str1[]
=
str1"- This, a sample string.";
p2 char str2*
;
printf ("Splitting string \"%s\" into tokens:\n",
)
strtok
- ;
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标
记。 - strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
strtok函数会改变被 *** 作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。) - strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。 - strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。 - 如果字符串中不存在更多的标记,则返回 NULL 指针。
使用演示
=strtok
(,
" ,.-" ) ;while
{
( str!=NULL )printf(
"%s\n" , pch)
; =strtok(strNULL,
pch " ,.-" ) ;str}return0;
} #pch include intmain
{
( )char*pch="zhangsan@bitedu.tech"
pch ; const char*= ".@";char
[
30 ]; char
*=
NULL ;strcpy(
{
, )p ; //将数据拷贝一份,处理arr数组的内容for
( =strtok sep ( ,)
; arr!=NULL;=
strtok (str NULL ,)
)printfarr( p"%s\n",)
;}str}#includearr# sepinclude# str include //必须包含的头文件int strmain()*; sep=fopen
{
("unexist.ent","r" str);
if
(
错误信息报告
strerror
strerror:返回错误码,所对应的错误信息。
使用演示
==NULL
)printf
("Error opening file unexist.ent: %s\n" ,
strerror ())
{
FILE; pFile//errno: Last error number
pFile return 0;}# include#include
int mainpFile ( )int
=0;char []errno="Test String.\n";
char
; while(
[
字符 *** 作
字符分类函数:
使用演示
])
=[
] ;if(
{
isupper i ( ))
= strtolower( ) ;putchar
( c)
; ++str;i}return
{
c 0 str;i}函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 ‘ 如果source和destination有任何的重叠,复制的结果都是未定义的 ’ 的时候并不会停下来。 void*my_memcpyc(void
c * ,constcvoid*
,size_tc)assert
i(!=
NULL
) ;assert
(
内存 *** 作函数
memcpy
memcpy
memcpy:从源source所指的内存地址的起始位置开始拷贝num个字节到目标destination所指的内存地址的起始位置中。注意:(内存 *** 作函数)
注意: 根据类型的大小确定num的大小。
- !=NULL)
模拟实现
;void *=;while destination( -- )* source( char num*
{
)=destination * (char*
);source = (char*
)+ p 1 destination;
= (numchar*
{
)+1;}destination return ;}和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。 如果源空间和目标空间出现重叠,就得使用memmove函数处理。 voidsource*
destination my_memmove (void*,destination const void*
source , size_t)assert(source != NULL)
;
assert p(
!=
注意: C语言规定memcpy只能拷贝,起始地址不一的两个空间,但是VS中实现的可以拷贝起始地址一样的空间。
C语言中要拷贝两个一样的起始地址,用的函数是memmove.因此我们在使用函数时要考虑函数的跨平台性。
- NULL)
函数实现原理
;void *=;if destination( < )//前向前 sourcewhile ( num--
{
)*destination ( char*)
=*source ( char*)
;= p ( destinationchar
* )destination + source1;
{
= (numchar*
{
)+1;}destination } else//后向后while(--source)
destination * ((char*destination ) +)
source = *((charsource * )+
)
;
}}
{
return ;num}int
{
main()char[]destination=num"abcdefj" ; memset(,'*',3source)num;printf
(
"%s"
, p)
;
memset
memset
memset:将 ptr 所指向的内存块的前 num 个字节设置为指定的值(解释为无符号字符)。
使用演示
int []=
{
10 arr,2 , 3,
4,arr5 ,6 ,7,
8,9} arr;memset
( arr1,1 , { 8);return0;}比较从ptr1和ptr2指针开始的num个字节 #include#includeintmain()char []
="DWgaOtP12df0"arr1; char[ ]="DWGAOTP12DF0"
; int;
=
memcmp
- memcmp
- 返回值如下
使用演示
(,
,sizeof
( ) );
{
if buffer1(0 ) printf(
"'%s' is greater than '%s'.\n" buffer2,, ) ;else
if n(
n<0 ) buffer1printf buffer2( "'%s' is less than '%s'.\n",buffer1, );
else printfn>("'%s' is the same as '%s'.\n" , ,);buffer1returnbuffer20;
} n buffer1buffer2
buffer1buffer2
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)