当前位置:网站首页>字符函数和字符串函数及其模拟实现(C语言)
字符函数和字符串函数及其模拟实现(C语言)
2022-07-21 05:04:00 【m0_63784118】
1. 函数介绍
1.1 strlen
1.2 strcpy
1.3 strcat
1.4 strcmp
1.5 strncpy
1.6 strncat
1.7 strncmp
1.8 strstr
1.9 strtok
1.10 strerror
1.11 memcpy
1.12 memmove
1.13 memcmp
1.函数介绍
1.1 strlen
size_t strlen ( const char * str );
字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。注意函数的返回值为size_t,是无符号的。
#include <stdio.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if(strlen(str2)-strlen(str1)>0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
模拟实现strlen
三种方式
1.
//计数器方式
int my_strlen(const char * str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}
2.
//不能创建临时变量计数器
int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}
3.
//指针-指针的方式
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
1.2 strcpy
char* strcpy(char * destination, const char * source );
Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
例如:
int main()
{
char arr1[30];
char arr2[]="qwert";
strcpy(arr1, arr2);
puts(arr1);
return 0;
}
模拟实现strcpy
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;//记录初始位置
assert(dest != NULL);
while((*dest++ = *src++))
{
;
}
return ret;
}
1.3 strcat
char * strcat ( char * destination, const char * source );
Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
例如:
int main()
{
char arr1[30]="abcde";
char arr2[30]="qwert";
strcat(arr1, arr2);
puts(arr1);
return 0;
}
模拟实现
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while(*dest)
{
dest++;
}
while((*dest++ = *src++))
{
;
}
return ret;
}
1.4 strcmp
int strcmp ( const char * str1, const char * str2 );
This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
例如:
int main()
{
char arr1[30]="abcde";
char arr2[30]="qwert";
printf("%d",strcmp(arr1, arr2));//比较的是从前往后每个字母的大小 如果第一个相同 则比较第二个 依次类推
return 0;
}
模拟实现
int my_strcmp (const char * src, const char * dst)
{
int ret = 0 ;
assert(src != NULL);
assert(dest != NULL);
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
1.5 strncpy
char * strncpy ( char * destination, const char * source, size_t num );
Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
例如:
int main()
{
char arr1[30];
char arr2[30]="qwert";
strncpy(arr1, arr2,3);
puts(arr1);
return 0;
}
1.6 strncat
char * strncat ( char * destination, const char * source, size_t num );
Appends the first num characters of source to destination, plus a terminating null-character. If the length of the C string in source is less than num, only the content up to the terminating null-character is copied
源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
拷贝num个字符从源字符串到目标空间后方
例如:
int main()
{
char arr1[30];
char arr2[30];
strcpy(arr1, "To be ");
strcpy(arr2, "or not to be");
strncat(arr1, arr2, 6);
puts(arr1);
return 0;
}
1.7 strncmp
int strncmp ( const char * str1, const char * str2, size_t num );
比较出现两个字符不一样或者一个字符串结束或者num个字符全部比较完。
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
例如:
int main ()
{
char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
int n;
puts ("Looking for R2 astromech droids...");
for (n=0 ; n<3 ; n++)
if (strncmp (str[n],"R2xx",2) == 0)
{
printf ("found %s\n",str[n]);
}
return 0;
}
1.8 strstr
char * strstr ( const char *str1, const char * str2);
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
例如:
int main ()
{
char str[] ="This is a simple string";
char * pch;
pch = strstr (str,"simple");
strncpy (pch,"sample",6);
puts (str);
return 0;
}
模拟实现
char * strstr (const char * str1, const char * str2)
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}
1.9 strtok
char * strtok ( char * str, const char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
例如:
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
1.10 strerror
char * strerror ( int errnum );
返回错误码,所对应的错误信息。
例如:
int main()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n",strerror(errno));
//errno: Last error number
return 0;
}
1.11 memcpy
void * memcpy ( void * destination, const void * source, size_t num );
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 '\0' 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的
例如:
int main()
{
char arr[] = "123456789";
char arr2[] = "987654321";
memcpy(arr, arr2, 4);
puts(arr);
return 0;
}
模拟实现
void* my_memcpy(void* des, const void* src, size_t num)
{
assert(des && src);
void* ret = des;
while (num--)
{
*(char*)des = *(char*)src;
des = (char*)des + 1;
src = (char*)src + 1;
}
return ret;
}
1.12 memmove
void* memmove(void* des, const void* src, size_t num);
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
例如:
int main ()
{
char str[] = "memmove can be very useful......";
memmove (str+20,str+15,11);
puts (str);
return 0;
}
模拟实现
void* my_memmove(void* des, const void* src, size_t num)
{
assert(des && src);
void* ret = des;
if (des < src)
{
while (num--)
{
*(char*)des = *(char*)src;
des = (char*)des + 1;
src = (char*)src + 1;
}
}
else
{
while(num--)
*((char*)des+num) = *((char*)src+num);
}
return ret;
}
1.13 memcmp
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较从ptr1和ptr2指针开始的num个字节
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
例如:
int main ()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
return 0;
}
边栏推荐
猜你喜欢
[PCB] production document sorting and output of circuit board drawing notes -- drawing board notes
图的邻接表及其深度优先(DFS)、广度优先(BFS)遍历
Hetai ht32 & taojingchi tjc--t0 serial port screen learning notes
Mask RCNN loading weight error
语义分割、实例分割
[PCB] Based on stm32f103rct6 joystick - Bluetooth module development board - drawing board notes sorting
Stm32f407-ov7670 (no FIFO) -onenet- upload camera pictures to onenet (EDP protocol)
4. 10 lines of code MNIST handwritten numeral recognition of paddlepaddle
Amy-Tabb机器人世界手眼标定(2、实验结果)
OPT101单片光电二极管和单电源互阻放大器使用说明
随机推荐
Bert原理概述
Yum install GCC error
Pytorch foundation module and Practice
Glory mobile refrigerator app activation
使用MATLAB GUI 设计工具开发小项目
[record] the operation of optisystem is stuck, and it is unable to click to close, input variable values and other solutions
(好数对)一个数组的值赋给另一个数组
跑TDD-net遇到的一些坑
OPT101单片光电二极管和单电源互阻放大器使用说明
1027打印沙漏
Account类
bert从入门到实践笔记本
二叉树的4种遍历的递归与非递归实现
深度剖析 string —— memset & memcmp
【PCB】基於STM32F103RCT6搖杆-藍牙模塊開發板-畫板筆記整理
2. Learn the vector calculation of paddlepaddle from scratch
合泰HT32 & 淘晶驰TJC--T0串口屏学习笔记
Self attention principle
Es aggregate statistical syntax
深度剖析 string —— strcat & strncat