C语言之库函数的模拟与使用
在我们学习C语言的过程中,难免会遇到这样的一种情况:
我们通常实现一个功能的时候,费尽心血的写出来,却有着满满的错,这时却有人来告诉你说:这个功能可以用相应的库函数来实现。
这时你的心里充满着***。但这并不算坏事,至少加深了你对它的认识与记忆。
所以,今天来漫谈一下 某些库函数的模拟与实现。
而这篇我们主要来介绍一些处理字符和字符串的库函数的使用和注意事项
内容大致如下:
1.求字符串长度 strlen
2.长度不受限制的字符串函数 strcpy strcat strcmp
3.长度受限制的字符串函数介绍 strncpy strncat strncmp
4.字符串查找 strstr strtok
5.错误信息报告 strerror perror
6.字符 *** 作
7.内存 *** 作函数 memcpy memmove memset memcmp
1.求字符串长度--strlen
正如所介绍那样,此函数的功能就是求一个字符串的长度。而我们所需要做的就是传一个字符指针进去。
示例:
#include <stdio.h>#include <string.h>int main (){ char szinput[256]; printf ("Enter a sentence: "); gets (szinput); printf (The sentence entered is %u characters long.\n,(unsigned)strlen(szinput)); return 0;}
结果:
在此函数的使用过程中我们需要注意以下几点:
1.字符串已经 ''2 作为结束标志
'.strlen函数返回的是在字符串中 3 前面出现的字符个数(不包含 )。
4.参数指向的字符串必须要以 结束。
#include.注意函数的返回值为size_t,是无符号的( 易错 )
我们来看一个对于第四点的例子:
#include <stdio.h>string< main(){ .h>constchar abcdef* str1 = ; charbbb* str2 = if) { printf( (strlen(str2) - strlen(str1) > str2>str1\n); } else { printf(srt1>str2\n;}srt1>str2
这个结果会是什么呢?
相信会有人给出int的结果,可编译器给出的结果却是:
为什么呢?
我们原以为 3-6=-3 这个式子没错啊,-3<0 执行 else 的结果
但 因为strlen的返回类型是一个unsigned形,所以相减之后的那个数会变为一个很大很大的数。
我们来模拟实现一下此函数
1.计数器方式char my_strlen( str){ *int; count = whilestr) { count (*; str++; } ++return count;}if2.递归实现
) (*str == else1 1 + my_strlen(str + );} s){3.指针-指针 实现
char s; * p =while) p (*p != return++ s;} p -长度不受限制的字符串函数
2.char@H_473_301@1.strcpy
@H_473_301@这个函数可谓是见名知意,字符串的拷贝函数,我们来看看介绍:
@H_473_301@
实例:
#include <stdio.h>Sample string str1[] = char40 str2[]; char]; strcpy(str2,str1); strcpy(str3, str3[copy successful); printf(str1: %s\nstr2: %s\nstr3: %s\n;}string
上述代码干了一个什么事呢?
将str1中的内容拷贝到str2中
又将 copy successful 拷贝到str3中
结果:
同样注意以下几点:
copIEs the C null pointed by source into the array pointed by destination,including the terminating char character (and stopPing at that point).模拟实现strcpy
源字符串必须以 结束。
会将源字符串中的 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。目标空间必须可变。
#include<assert.h>char* my_strcpy( src){ * dest,char dest; assert(dest * ret =//!= NulL); 断言保证dest不为空指针断言保证src不为空指针 assert(src != NulL); while )) { ; } ((*dest++ = *src++ ret;}char2.strcat-连接两个字符串
介绍如下:
实例:
#include <stdio.h>80 str[are ]; strcpy(str,1)">these ); strcat(str,1)">strings concatenated.); puts(str); ;}string
作用:
先将 these 复制到 str 中,在逐次将 strings 、are、concatenated 连接到str上
结果:
注意:
Appends a copy of the source string to the destination null. The terminating in character is destination null overwritten by the first character of source,and a is-character new included at the end of the string in formed by the concatenation of both destination.1.源字符串必须以 char 结束。2.目标空间必须有足够的大,能容纳下源字符串的内容。目标空间必须可修改。
还值得注意的一点就是:若自己追加自己将会“永无休止”的循环下去,为什么呢?
模拟实现
#include<assert.h> dest; assert(dest * my_strcat( NulL); assert(src != NulL); !=while找到 { dest的位置 (*dest) while在此 { ; } 位置上覆盖新的内容++ ret;} ((*dest++ = *src++))charapplechar
3.strcmp-字符串比较函数
切记:不能用 == 来判断两个字符串是否相等
介绍:
实例:
#include <stdio.h>do key[] = { printf(Guess my favorite fruit? buffer[); fflush(stdout); scanf(%79swhile); puts(Correct answer!); (strcmp(key,buffer) != ;}stringis reached.标准规定:第一个字符串大于第二个字符串,则返回大于0的数字第一个字符串等于第二个字符串,则返回0第一个字符串小于第二个字符串,则返回小于0的数字
作用:
定义一个key来表示自己喜欢的水果,
让用户不断来输入,
直到用户输入所指定内容
最后输出 correct answer
结果:
注意:
This function starts comparing the first character of each int. If they are equal to each other,it continues with the following pairs until the characters differ or until a terminating charint
比较是比的相应字符的ASCII码值,如果相等,则比较下一个以此类推.....
模拟实现:
; assert(src my_strcmp( NulL); assert(dest * src,1)"> dest){ NulL); ret = while!=char!=chardest不为空,且如果相减结果为0,就继续循环 (!(ret = *(unsigned { *)src - *(unsigned dest; *)dest) && *dest)if) ret ++src,++; else (ret < if= -) ret ; } (ret);} (ret > char= s2); while
#include<assert.h>s2) { *s1,1)">s2){ assert(s1 &&if) (*s1 == *; s1; s2 (*s1 == returns2;}++#include ++char *s1 - *To be or not to be
3.长度受限制的字符串函数介绍1.strncpy-从原始串复制自定义个字符到新串中
介绍:
实例:
; <stdio.h>]; str1[]= ]; /* copy to sized buffer (overflow safe): */ strncpy ( str2,sizeof(str2) ); partial copy (only 5 chars): ); str3[5' strncpy ( str3,1)">5 null character manually added puts (str1); puts (str2); puts (str3); ] = 0; stringsignaled by a null;
}
作用:
将str1中所有的字符复制到str2中
将str1中的前五个字符复制到str3中
结果:
注意:
copIEs the first num characters of source to destination. If the end of the source C is (which charchar-character) source); found before num characters have been copIEd,destination paddedwith zeros until a total of num characters have been written to it.
拷贝num个字符从源字符串到目标空间。如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
模拟实现:
destination; destination[num] * my_strncpy(while* destination,1)"> source,size_t num){ assert(destination &&) { if= ) { (num--; break (*source == ; } *destination = ret;}char20*destination++ = *source++); puts(str1);2.strncat--从原始串取自定义个字符连接到新串中
介绍:
示例:
#include <stdio.h>;} str1[null]; strcpy(str1,1)">To be ); strcpy(str2,1)">or not to be); strncat(str1,1)">6character.If the length of the C string
作用:
将str2中的前6个字符连接到str1后面
结果:
注意:
Appends the first num characters of source to destination,plus a terminating in-isis char source destination; less than num,only the content up to the terminating nullcharacter while copIEd.
模拟实现:
找到'* my_strncat(放置) { ; (*destination);; } } destination[num] = ret;};char 5*destination++ = *source++R2D2"C3PO3.strncmp-自定义个字符比较
比较方式与strcmp相同
介绍:
示例:
#include <stdio.h>R2A6 str[][ }; ] = { n; puts(Looking for R2 astromech droIDs...,for03if2) { printf( (n = found %s\n; n < ;}; n++比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。(strncmp(str[n],1)">R2xxint) == char str2); if
作用:
比较各字符串的前两个字符是否为R2,如果相同,则输出
结果:
注意:
str2)) {
模拟实现:
#include <stdio.h>return my_strncmp(str2; } str1* str1,1)"> str2,size_t num){ assert(str1 &&; str2;} ((*str1 != *charThis is a simple string *str1 - * pch; pch ++if++); puts(pch);4.字符串查找函数1.strstr-在一个字符串中查找另一个字符串是否存在并返回相应的地址
介绍:
示例:
#include <stdio.h>;} str[] = innull= strstr(str,1)">simpleif (pch != NulL) strncpy(pch,1)">sampleischar
作用:
在str中查找simple是否存在
结果:
注意:
Returns a pointer to the first occurrence of str2 str2){ assert(str1 str1,or a char pointer str1; str2 start) { not part of str1.
模拟实现:
#include <stdio.h>char* my_strstr( start; &&char* start = str2; whilee2)) { e1* e1 =; e2; } * e2 =if) { ((*e1 == *e2) && (*e1) && (*return++)start; } start++ NulL;}EG:- This,a sample string. (*e2 == pch; printf(Splitting string \"%s\" into tokens:\n (while++ NulL) { printf(2.strtok-字符串分割函数
介绍:
实例:
#include <stdio.h>%s\n;}charchar (pch !=string#include main(){ file
作用:
将所给字符串用所给分隔符分割开;
结果:
注意:
pfile; pfile * strtok ( unexist.ent * str,1)">char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \ 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被 *** 作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NulL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NulL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NulL 指针。
5.错误信息报告
1.strerror-返回错误码,所对应的错误信息。
介绍:
示例:
#include <stdio.h>r.h>if<errno.h>//必须包含的头文件 NulL) printf(*Error opening file unexist.ent: %s\n= fopen(;}使用时必须包含头文件:errno.hrb (pfile == NulL) perror(The following error occurred fclose(pfile);
结果:
注意:
;}2.perror-打印对应的错误信息
示例:
#include <stdio.h>#include i; charc3po...; i
结果:
6.字符分类函数:
注意:
比较时,是一个一个字符的去比较
示例及结果:
#include <stdio.h>while<ctype.h>; printf (The first %d characters are Alphanumeric.\n str[]=;}int=C++ (isalnum(str[i])) i++while (str[i]) { if
#include <stdio.h> (isAlpha(str[i])) printf( i = character %c is Alphabetic\n printf(character %c is not Alphabetic\n;}struct { char age;} person,person_copy;char
7.内存 *** 作函数
内存 *** 作函数不仅可以处理字符串,还可以处理结构体,整形数组等。
1.memcpy--以字节为单位复制介绍:
示例:
#include <stdio.h>PIErre de Fermat; using memcpy to copy string: name[ memcpy(person.name,myname,strlen(myname) ); person.age myname[] = 46 using memcpy to copy structure: memcpy(person_copy: %s,%d \n+ ;}= voIDvoIDvoID&person_copy,&person,1)">(person)); printf() { char
结果:
注意:
voID * memcpy ( voID * destination,const voID * source,size_t num );
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的
模拟实现:
char* my_memcpy( ret;}* destination,1)">voID*memmove can be very useful......* ret =; memmove (str*((20*)destination)++ = *((15*)source)++); puts (str);2.memmove
介绍:
示例:
#include <stdio.h>;}memmove和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。+voID,str+voID,1)">11 dest; assert(dest src);
结果:
注意:
if
模拟实现:
src) { * my_memmove(前->后* dest,1)">src,size_t count){ while&&) { char (dest <)src; )dest; )src; } } (count-- { *(后->前*)dest = *() { ++(char++(char count); } } ret;} almost every programmer should kNow memset!*(('*)dest + count) = *((voID*)src +voIDvoID3.memset
介绍:
示例:
#include <stdio.h> src; ; memset (str,1)">-) { ,1)">;}
结果:
模拟实现:
char * Memset(char* src,1)"> ch,size_t count){ assert(src !=)ch; src * start =char start;}*(char*)src = (DWgaOtP12df0char= (DWGAOTP12DF0*)src + ;4.memcmp
介绍:
示例:
#include <stdio.h> n; n buffer1[] = if0 buffer2[] = '%s' is greater than '%s'.\nif'%s' is less than '%s'.\n=memcmp ( buffer1,buffer2,1)">(buffer1) ); else (n>'%s' is the same as '%s'.\n) printf (;}int (n<voID方法1 printf ({ assert(p1); assert(p2); char
结果:
注意:
比较从ptr1和ptr2指针开始的num个字节
返回值同strcmp
模拟实现:
)p1; my_memcmp(char* p1,1)">voID* p2,size_t count))p2; whileif* dest = (returnsrc;}* src = ( (count-- && (*dest++ == *src++ (count == *dest - *
若有有错之处,还望大家多多指点!!!
本次讲解就到这了,如果大家对于函数的模拟实现都能掌握,那么大家肯定对于上述函数有了深刻的理解。
总结
以上是内存溢出为你收集整理的C语言之库函数的模拟与使用全部内容,希望文章能够帮你解决C语言之库函数的模拟与使用所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)