C语言:字符串操作函数,内存操作函数实现

https://www.52pojie.cn/thread-576232-1-1.html



*******前言 *******

我数一下,我发了几个帖子,1、2、3?

哈哈哈,没几个哈,感谢吾爱,让我学到了很多,乐于分享,共同进步!

最近也是在学c语言,也看了少许面试题

指针,数据结构,字符串操作肯定是重点

今天分享出来的是,一些字符串操作函数和一些内存操作函数的手动实现

内容应该不难,如有错误还请朋友们指出,我会认真改正的,希望一起学习进步


******* 目录 *******

字符串常见函数:

strlen、strcmp、strcpy、strlwr、strrev、strset、strstr、strupr、itoa、atoi、atof、ftoa

(希望初学者能够尝试用 下标访问 和 指针访问两种方式实现)

内存操作少许函数:

memccpy、memchr、memcpy、memicmp、memmove、memset

(希望读者能够认真手动实现)


当然实际开发中,这些函数直接调用就行了,

但是面试的时候,这是基础知识,这是考察你的基本功 和 砍你工资的大斧

因为简单,所以代码注释少,有疑惑的请告诉我,乐于交流

*******字符串函数 *******

1.strlen:计算字符串长度(不包含'\0')

实现想法:遍历字符串,直到'\0'结束

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
//指针法
unsigned int mystrlenaddr( const char * str)  //为什么使用const char,我们只计数不对原数据进行改变
{
         int length = 0;  //长度初始化为0
         while (*str++)
         {
                 length++;
         }
         return length;
}
 
 
void main()
{
         char * str = "fengcong is fucking too handsome" //32个
         //printf("%d\n", strlen(str));
         printf ( "%d\n" , mystrlenaddr(str));
 
         system ( "pause" );
}

2.strcmp:比较字符串大小(一般用于字符串排序)

实现想法:依次从字符串开始一直找到不同的那个字符进行比较,得出大小

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
 
//掌握指针法
int mystrcmp( char const * str1, const char * str2)
{
         while (*str1 == *str2 && *str1 != '0' //一直找到两个字符串不同的地方
         {
                 str1++;
                 str2++;
         }
         if (*str1 > *str2)
                 return 1;
         else if (*str1 < *str2)
                 return -1;
         else
                 return 0;
}
 
void main()
{
         char * str = "feng1" ;
         char * str1 = "feng2" ;
 
         //printf("%d\n", strcmp(str, str1));
 
         printf ( "%d\n" , mystrcmp(str, str1));
 
 
         system ( "pause" );
}

3.strcpy:用于字符串复制(复制包含'\0')

实现想法:一直复制到'\0'结束

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
 
//指针法
char * mystrcpyaddr( char * dest, const char * source)
{
         if (dest == NULL || source == NULL)
         {
                 return NULL;   //如果目的操作或者源为空,那么久直接返回
         }
 
         while (*dest++ = *source++)  //装X写法
                 ;
         return dest;
}
 
//下标法
char * mystrcpyindex( char * dest, const char * source)
{
         if (dest == NULL || source == NULL)
         {
                 return NULL;   //如果目的操作或者源为空,那么久直接返回
         }
         int i = 0;
         while (source != '\0' )
         {
                 dest = source;
                 i++;
         }
         dest = source; //因为要把最后的\0拷贝过去
         return dest;
}
 
void main()
{
         char * str = "fengcong is fucking too handsome" ;
         char str1[100]; //目的字符数组
         //strcpy(str1, str);
         //printf("%s\n", str1);
         mystrcpyindex(str1, str);
         printf ( "%s\n" , str1);
 
 
         system ( "pause" );
}

4.strlwr:大写转小写

实现想法:遍历字符串,遇到大写转为小写

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
char * mystrlwr( char * str)
{
         char * p1 = str;
         while (*p1)
         {
                 if (*p1 >= 'A' && *p1 <= 'Z' )
                 {
                         *p1 += 32;
                 }
                 p1++;
         }
         return str;
}
 
void main()
{
         char str[50] = "FENGCONG IS FUCKING TOO HANDSOME" ;
         //printf("%s\n", _strlwr(str));
         printf ( "%s\n" , mystrlwr(str));
 
 
         system ( "pause" );
}

5.strrev:字符串逆转

实现想法:头首交换,直到中间

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
 
char * mystrrev( char * str)
{
         char * p2 = str;
         char * p1 = str;
         while (*p1++)
         {
                 ;
         }
         p1 -= 2; //回到最后一个字符
         while (p1 - p2 >= 1)
         {
                 char temp = *p1;
                 *p1 = *p2;
                 *p2 = temp;
                 p2++;
                 p1--;
         }
         return str;
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         //_strrev(str);
         //printf("%s\n", str);
         printf ( "%s\n" ,mystrrev(str));
 
         system ( "pause" );
}

6.strset:将字符串全部设成某字符

实现想法:遍历字符串,每个字符设置某字符,直至'\0'

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#define  _CRT_SECURE_NO_WARNINGS
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
 
char * mystrset( char * str, int value)
{
         char * p1 = str;
         while (*p1)
         {
                 *p1 = value;
                 p1++;
         }
         return str;
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         //printf("%s\n", _strset(str, 'A'));
         printf ( "%s\n" , mystrset(str, 'A' ));
 
         system ( "pause" );
}

7.strstr:寻找母串中是否存在某个子串(稍难)

实现想法:依次比对

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
//下标 法
char * mystrstrindex( char * const momstr, const char * const sonstr) //前者指针指向的数据可变,但是指针不可变,后者都不可变
{
         int momlen = strlen (momstr); //母串的长度
         int sonlen = strlen (sonstr); //子串的长度
 
         for ( int i = 0; i < (momlen - sonlen); i++)  //从0开始循环母串,到momlen-sonlen停止
         {
                 int flag = 1;
                 for ( int j = 0; j < sonlen; j++)
                 {
 
                         if (momstr[i + j] != sonstr[j])
                         {
                                 flag = 0;
                                 break //如果出现不相等就 退出循环,继续从下面一个寻找
                         }
                 }
                 if (flag)
                 {
                         return (&momstr);
                 }
         }
         return NULL;
}
 
//指针法
char * mystrstraddr( char * const momstr, const char * const sonstr)
{
         char * mstr = momstr;  //母串
 
         while (*mstr)
         {
                 char * sstr = sonstr;  //子串
                 char * momnowstr = mstr;  //记录现在母串的位置
                 int flag = 1;
                 while (*sstr != 0)
                 {
                         if (*sstr != *momnowstr || *momnowstr == '0' )
                         {
                                 flag = 0;
                                 break ;
                         }
                         momnowstr++;
                         sstr++;
                 }
                 if (flag)
                 {
                         return mstr;
                 }
                 
                 mstr++; //母串对比位置+1
         }
         return NULL;
}
 
void main()
{
         char * str = "fengcong is too fucking handsome" ;
         //printf("%p", strstr(str, "fengcong"));
         //printf("%p", mystrstrindex(str, "engcong"));
         printf ( "%p" , mystrstraddr(str, "some" ));
 
         system ( "pause" );
}

8.strupr:小写转大写

实现想法:依次遍历,遇到小写转为大写

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
char * mystrupr( char * str)
{
         char * p1 = str;
         while (*p1)
         {
                 if (*p1 >= 'a' && *p1 <= 'z' )
                 {
                         *p1 -= 32;
                 }
                 p1++;
         }
         return str;
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         //printf("%s\n", _strupr(str));
         printf ( "%s\n" , mystrupr(str));
 
 
         system ( "pause" );
}

9.itoa:整数转字符串

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
 
char * myitoa( int value, char * str)
{
         char * pstr = str; //str本身不能改变,一会要返回str
         if (value < 0)
         {
                 *pstr = '-' ;
                 pstr++;
                 value *= -1; //转变为正数处理
         }
         int wei = 1;  //数至少一位
         int ivalue = value; //用于测试长度
         while ((ivalue /=   10) != 0)
         {
                 wei++;
         }
 
         pstr += wei-1;
         while (value % 10 != 0)
         {
                 *pstr-- = (value % 10)+ '0' ;
                 value /= 10;
         }
         return str;
}
 
void main()
{
         int num = -45644;
         char str[20] = { 0 };
 
         printf ( "%s" , myitoa(num, str));
 
 
 
         system ( "pause" );
}

10.atoi:字符串转整数(遇到非数字字符结束)

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
 
int myatoi( const char * str)
{
         if (str == NULL)
         {
                 return 0; 
         }
         int num = 0; //需要返回的值
         int flag = 1; //记录正负号
         if (*str == '-' )
         {
                 flag = -1;
                 str++;
         }
         else if (*str == '+' )
         {
                 str++;
         }
 
         while (*str >= '0' && *str <= '9' )
         {
                 num= (num * 10 + (*str - '0' ));
                 str++;
         }
 
         return num*flag;
}
 
void main()
{
         char str[20] = "-57124" ;
         int num = 0;
 
         printf ( "%d\n" ,myatoi(str));
 
 
 
         system ( "pause" );
}


11.atof:字符串转浮点数

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
 
double myatof( char const * str)
{
         if (str == NULL)
                 return 0;
 
         //首先判断有无符号位
         int flag = 1;
         if (*str == '-' )
         {
                 flag = -1;
                 str++;
         }
         if (*str == '+' )
         {
                 str++;
         }
         int zhengshu = 0;  //存储整数部分
         while (*str >= '0' && *str <= '9' )
         {
                 zhengshu = zhengshu * 10 + (*str - '0' );
                 *str++;
         }
         //整数部分循环完了
         double xiaoshu = 0.0;  //存储小数部分
         //因为不明符号停止整数循环
         if (*str != '.' )
         {
                 return (flag * zhengshu);
         }
         else //代表遇到. 结束
         {
                 str++; //指向小数部分第一位
                 double i = 0.1;
                 while (*str >= '0' && *str <= '9' )
                 {
                         xiaoshu = xiaoshu + (*str - '0' )*i;
                         i /= 10;
                         str++;
                 }
 
                 return flag *(zhengshu + xiaoshu);
         }
}
 
void main()
{
         char str[20] = "2.1554" ;
         double db = 0.0;
         printf ( "%lf\n" , myatof(str));
 
 
         system ( "pause" );
}

12.ftoa:浮点数转字符串(浮点数存储不准确,可能有少许误差)

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
 
char * myftoa( double db, char * str)
{
         char * pstr = str;
         //先判断 符号位
         if (db < 0)
         {
                 *pstr = '-' ;
                 db *= -1;  //转为正数处理
                 pstr++;
         }
         //整数部分
         int zhengshu = ( int )db;
         int izhengshu = zhengshu; //牺牲于记录整数长度
         int wei = 1;  //整数部分至少一位
         while ((izhengshu /= 10) != 0)
         {
                 wei++;
         }
         pstr += wei - 1;
         for ( int i = 0; i < wei; i++)
         {
                 *pstr-- = zhengshu % 10 + '0' ;
                 zhengshu /= 10;
         }
         pstr += (wei+1);
         *pstr = '.' ;
         pstr++;
         //小数部分
         double xiaoshu = db - ( int )db;
         for ( int i = 0; i < 6; i++)
         {
                 *pstr++ = ( int )(xiaoshu * 10) + '0' ;
                 xiaoshu = xiaoshu * 10 - ( int )(xiaoshu * 10);
         }
         return str;
}
 
void main()
{
         double db = -2.11;
         char str[20] = { 0 };
         printf ( "%s\n" , myftoa(db,str));
         
 
 
         system ( "pause" );
}

*******内存操作函数 *******

1.memccpy:内存拷贝,直到一个值结束

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
//下标法
void * mymemccpybyindex( void * dest, const void * sor, int val, size_t len)
{
         if (dest == NULL || sor == NULL)
         {
                 return NULL;
         }
         for ( int i = 0; i < len; i++)
         {
                 if ( ((( char *)dest) = (( char *)sor)) == val)
                         return dest;
         }
         return dest;
}
//指针法
void * mymemccpybyaddr( void * dest, const void * sor, int val, size_t len)
{
         if (dest == NULL || sor == NULL)
         {
                 return NULL;
         }
         char * pdest = dest;
         char * psor = sor;
         char * plast = ( char *)sor + len;
         while (psor < plast)
         {
                 if ((*pdest++ = *psor++) == val)
                         return dest;
 
         }
         return dest;
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         char * pstr = ( char [50]) { 0 };  //在栈上开辟一段内存
         //printf("%s\n", memccpy(pstr,str,'s',32));
         printf ( "%s\n" , mymemccpybyaddr(pstr, str, 'f' , 32));
 
         system ( "pause" );
}

2.memchr:某段内存中寻找某个值

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
 
void * mymemchar( void * buf, int val, size_t size)
{
         if (buf == NULL)
         {
                 return NULL;
         }
         char * p = buf;
         char plast = p + size;
         while (p < plast)
         {
                 if (*p == val)
                 {
                         return p;
                 }
                 p++;
         }
         return NULL;
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         printf ( "%s\n" , mymemchar(str, 'g' , 8));
 
 
         system ( "pause" );
}

3.memcpy:拷贝某段内存

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
//下标法
void * mymemcpybyindex( void * dest, const void * sor, size_t len)
{
         if (dest == NULL || sor == NULL)
         {
                 return NULL;
         }
         for ( int i = 0; i < len; i++)
         {
                 (( char *)dest) = (( char *)sor);
         }
         return dest;
}
//指针法
void * mymemcpybyaddr( void * dest, const void * sor, size_t len)
{
         if (dest == NULL || sor == NULL)
         {
                 return NULL;
         }
         char * pdest = dest;
         char * psor = sor;
         char * plast = ( char * )sor + len;
         while (psor < plast)
         {
                 *pdest++ = *psor++;
 
         }
         return dest;
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         char * pstr = ( char [50]) { 0 };  //在栈上开辟一段内存
 
         //printf("%s\n", memcpy(pstr, str, 32));
         printf ( "%s\n" , mymemcpybyaddr(pstr, str, 31));
 
 
         system ( "pause" );
}

4.memicmp:比较某段内存大小(一个字节一个字节比较,像strcmp)

注意:切不可用来比较整数,除非一字节整数,因为整数存储方式是高位高字节

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
 
int mymemicmpbyaddr( const void * buf1, const void * buf2, size_t size)
{
         char * p1 = buf1;
         char * p2 = buf2;
         int i = 0;
         while (*p1 == *p2 && i < size)
         {
                 p1++;
                 p2++;
                 i++;
         }
         if (*p1 > *p2)
         {
                 return 1;
         }
         else if (*p1 < *p2)
                 return -1;
         else
                 return 0;
 
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         char str1[50] = "fengfeng is fucking too handsome" ;
 
         printf ( "%d\n" , mymemicmpbyaddr(str, str1, 32));
         system ( "pause" );
}

5.memmove:和memcpy类似,但是memmove采用了中间空间,memcpy是直接拷贝

两者区别之处在于当拷贝地址重复的时候,结果不一样(比较代码可知)

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<malloc.h>
void * mymemmove( void * dest, const void * sor, size_t size)
{
         char * ptemp = malloc (size); //中间 地址
         memcpy (ptemp, sor, size);
         memcpy (dest, ptemp, size);
         free (ptemp);
}
 
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         //memmove(str + 3, str + 4, 2);
         mymemmove(str + 3, str + 4, 2);
         printf ( "%s\n" ,str);
 
 
 
         system ( "pause" );
}

6.memset:对指定内存每个字节赋某个值

[C]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
 
//下标法
void * mymemsetbyindex( void * dest, int val, size_t len)
{
         if (dest == NULL)
         {
                 return NULL;
         }
         if (len == 0)
         {
                 return dest;
         }
         char * p = dest;
         for ( int i = 0; i < len; i++)
         {
                 p = val;
         }
         return dest;
}
 
//指针法
void * mymemsetbyaddr( void * dest, int val, size_t len)
{
         if (dest == NULL)
         {
                 return NULL;
         }
         if (len == 0)
         {
                 return dest;
         }
         char * p = dest;
         char * plast = p + len;
         while (p < plast)
         {
                 *p++ = val;
         }
         return dest;
}
 
void main()
{
         char str[50] = "fengcong is fucking too handsome" ;
         //printf("%s\n", memset(str, 65, 8));
         printf ( "%s\n" , mymemsetbyaddr(str, 65, 8));
         system ( "pause" );
}
*******结束语 *******

内容应该都不难,希望大家讨论讨论,认真实现,不要让这基本功成为

面试官挥动大斧砍你工资的把柄

文中代码区,少许地方少*,不知道为什么,请注意添加
再会了,还是那句话,你们开心就好,拜个早年!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值