目录
一、求字符串长度
1.strlen()函数
1.函数功能
计算字符串长度的函数,返回类型是size_t,即无符号整型。
2.函数原形
size_t strlen(const char* str);
3.模拟实现
代码:
//模拟实现strlen()函数
unsigned int my_strlen(const char* str)
{
char* tmp = str;
int len = 0;
while (*tmp)
{
len++;
tmp++;
}
return len;
}
二、长度不受限制的字符串操作函数
1.strcpy()函数
1.函数功能
拷贝字符串(包括'\0'),读到'\0'就停止拷贝。
2.函数原形
char * strcpy ( char * destination, const char * source );
3.模拟实现
代码:
//模拟实现strcpy()函数
//将str2拷贝到str1中
char* my_strcpy(char* str1, const char* str2)
{
char* tmp = str1;
while (*str2)
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return tmp;
}
2.strcat()函数
1.函数功能
实现字符串的连接。
2.函数原形
char* strcat(char* destination, const char* source);
3.模拟实现
代码:
//模拟实现strcat()函数
char* my_strcat(char* str1, const char* str2)
{
char* tmp = str1;
while (*++str1);//循环结束后*str1是'\0'
while (*str2)
{
*str1 = *str2;
str1++;
str2++;
}
*str1++ = '\0';
return tmp;
}
3.strcmp()函数
1.函数功能
比较两个字符串的大小。
比较的是两个字符串对应字符的ASCII码值,第一个字符串字符大于第二个字符串中对应字符时函数返回大于0的数,小于时返回小于0的数,等于时返回0。
2.函数原形
int strcmp ( const char * str1, const char * str2 );
3.模拟实现
代码:
//模拟实现strcmp()函数
int my_strcmp(const char* str1, const char* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
return (*str1 - *str2);
}
三、长度受限制的字符串操作函数
1.strncpy()函数
1.函数功能
拷贝字符串(前n个字符(不包括'\0')),将前n个字符拷贝完成后,将目标空间的第n+1个字符置为'\0',以终止拷贝。
2.函数原型
char * strncpy ( char * destination, const char * source, size_t num );
3.模拟实现
代码:
//模拟实现strncpy()函数
char* my_strncpy(char* str1, const char* str2,unsigned int n)
{
char* tmp = str1;
while (n)
{
*str1 = *str2;
str1++;
str2++;
n--;
}
*str1 = '\0';
return tmp;
}
2.strncat()函数
1.函数功能
将源字符串的前n个字符连接到目标字符串,其后加'\0'结束字符串。
2.函数原形
char * strncat ( char * destination, const char * source, size_t num );
3.模拟实现
代码:
//模拟实现strncat()函数
char* my_strncat(char* str1, const char* str2,unsigned int n)
{
char* tmp = str1;
while (*++str1);
while (n)
{
*str1 = *str2;
str1++;
str2++;
n--;
}
*str1++ = '\0';
return tmp;
}
3.strncmp()函数
1.函数功能
比较两个字符串的前n个字符。
2.函数原形
int strncmp ( const char * str1, const char * str2, size_t num );
3.函数模拟
代码:
//模拟实现strcmp()函数
int my_strcmp(const char* str1, const char* str2,unsigned int n)
{
while (*str1 == *str2 && n)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
n--;
}
return (*str1 - *str2);
}
八、字符串查找
1.strstr()函数
1.函数功能
找到字符串中的子字符串,并返回第一次出现的子字符串的首地址。
2.函数原形
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
3.模拟实现
代码:
//模拟实现strstr()函数
char* my_strstr(char* str1, const char* str2)
{
char* s1 = str1;
char* s2 = str2;
char* p1 = s1;
char* p2 = s2;
while (*p1)
{
while (*s1 == *s2 && *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
return p1;
else
{
p1++;
s1 = p1;
s2 = p2;
}
}
return NULL;
}
2.strtok()函数
1.函数功能
截断字符串(按标识符截断)。
2.函数原形
char * strtok ( char * str, const char * delimiters );
3.实现原理
代码:
//strtok()函数的应用
int main()
{
char arr[] = "http@qq.com";
char buf[200] = { 0 };
strcpy(buf, arr);//buf[200]="http@qq.com"
const char* p = "@.";//标识符
char* str = NULL;
for (str=strtok(buf, p); str!=NULL; str=strtok(NULL, p))
{
printf("%s\n", str);
}
return 0;
}
运行结果:
解释:
strtok()函数传参的时候,第一个参数为截断字符串的起始地址。第一次传参的时候传所需截断字符串的首地址;从第二次开始,因为第一次截断时strtok() 记住了标识符的下一个字符的地址,所以只需传空指针NULL;如需截断另一个新的字符串,只需将新字符串的地址传给第一个参数即可。
四、错误信息报告
1.strerror()函数
1.函数功能
获取指向错误消息字符串的指针(把错误码转化为错误信息)。
2.函数原形
char * strerror ( int errnum );
3.实现原理
代码:
#include <stdio.h>
#include <string.h>
#include <errno.h>
//strerror
//把错误码转换成错误信息
int main()
{
printf("%s\n", strerror(0));
printf("%s\n", strerror(1));
printf("%s\n", strerror(2));
printf("%s\n", strerror(3));
printf("%s\n", strerror(4));
printf("%s\n", strerror(5));
//错误码记录到错误码的变量中
//errno - C语言提供的全局的错误变量
printf("%s\n",strerror(errno));
return 0;
}
运行结果:
五、内存操作函数
1.memcpy()函数
1.函数功能
内存拷贝(一般编译器不支持目标空间和被拷贝的部分有重叠),因拷贝内容的类型不确定,故以单个字节为单位进行拷贝,返回目标空间的起始地址。
2.函数原形
void * memcpy ( void * destination, const void * source, size_t num );
3.模拟实现
代码:
#include <stdio.h>
#include <assert.h>
//模拟实现memcpy()
//memcpy()函数的功能因编译器而异,大部分编译器不能处理有重叠的情况,此处不予考虑
void* my_memcpy(void* destination, const void* source, unsigned int n)
{
assert(destination && source);
//为了代码的可移植性,因为拷贝对象的大小不确定,所以以单个字节为单位拷贝
char* src = (char*)source;
char* des = (char*)destination;
while (n)
{
//从前往后拷贝
*des = *src;
des++;
src++;
n--;
}
return destination;//返回目的空间的首地址,方便链式访问
}
函数原理:
void*可以接受任意类型变量的地址,因为变量大小的不确定性,将指针强转为char*(指针类型决定解引用可以访问的空间大小,char*解引用访问一个字节大小的空间),然后一个字节一个字节的拷贝。
2.memmove()函数
1.函数功能
内存拷贝(与memcpy()函数相似,memmove()函数能处理目标空间和被拷贝空间有重叠的情况)。
2.函数原形
void * memmove ( void * destination, const void * source, size_t num );
3.模拟实现
代码:
#include <stdio.h>
#include <assert.h>
//模拟实现memmove()
void* my_memmove(void* destination,const void* source,unsigned int n)//n为拷贝的字节数
{
assert(destination && source);
//为了代码的可移植性,因为拷贝对象的大小不确定,所以以单个字节为单位拷贝
char* src = (char*)source;
char* des = (char*)destination;
if (src < des && src + n - 1 > des)
{
des = des + n - 1;
src = src + n - 1;
//重叠且source在前:从后往前拷贝
for (int i = 0;i < n;i++)
{
*des = *src;
des--;
src--;
}
}
else
{
//没有重叠的空间或者重叠但source在后:从前往后拷贝
for (int i = 0;i < n;i++)
{
*des = *src;
des++;
src++;
}
}
return destination;//方便链式访问
}
函数原理:
处理目标空间和被拷贝空间有重叠的时候有两种情况,第一种,目标空间在前,被拷贝空间在后,从前往后拷贝(与不重叠的情况拷贝顺序相同);第二种,目标空间在后,被拷贝空间在前,从后往前拷贝。
3.memset()函数
1.函数功能
将目标空间的前num个字节的空间都赋值为value。
2.函数原形
void * memset ( void * ptr, int value, size_t num );
3.模拟实现
代码:
//模拟实现memset()函数
void* my_memset(void* ptr, int value, unsigned int n)
{
char* p = (char*)ptr;
char tmp = (unsigned char)value;
while (n)
{
*p = tmp;
p++;
n--;
}
return ptr;
}
int main()
{
char str[] = "almost every programmer should know memset!";
my_memset(str, '-', 6);
puts(str);
return 0;
}
运行结果:
4.memcmp()函数
1.函数功能
比较两个内存空间内对应内容的大小,以单个字节为单位进行比较,比较两个指针指向空间前num个字节的内容,与strcmp()函数不同的是,遇到'\0'也不会停止比较。
2.函数原形
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
3.模拟实现
代码:
#include <stdio.h>
//模拟实现memcmp()函数
int my_memcmp(const void* ptr1, const void* ptr2, unsigned int n)
{
char* p1 = (char*)ptr1;
char* p2 = (char*)ptr2;
while (*p1 == *p2)
{
if (n == 0)
return 0;
else
{
p1++;
p2++;
n--;
}
}
return *p1 - *p2;
}
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = my_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;
}
运行结果:
这篇文章写到这里就结束啦,看到错误的话烦请指正,谢谢大家!!!