目录
-
求字符串长度
-
strlen函数
size_t strlen ( const char * str );
strlen函数返回类型是size_t,size_t其实就是无符号整形
1.字符串以'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数(不包括'\0')。
2.参数指向的字符串必须要以'\0'结束。
例:
3.模拟实现strlen
//创建临时变量方式
int my_strlen(const char*str)
{
assert(str!=NULL);//保证指针的有效性,使用时记得引用<assert.h>头文件
int count=0;
while(*str)//当*str不为'\0'的时候进入循环
{
count++;
str++;
}
return count++;
}
//递归的方式
int my_strlen(const char*str)
{
if(*str=='\0')
return 0;
else
return 1+my_strlen(str+1);
}
//指针减指针的方式
int my_strlen(const char*str)
{
char*p=str;//把起始地址赋值给p,让p进行while循环
while(*p!='\0')
{
p++;
}
return p-str;
}
-
长度不受限制的字符串函数
-
strcpy 字符串复制函数
char * strcpy ( char * destination, const char * source );
1.源字符串(source指针指向的字符串)必须以'\0'结束
2.strcpy函数将source指针指向的字符串(包括'\0')复制到dest指定的位置。复制或追加字符串时不执行溢出检查。如果源字符串和目标字符串重叠,则strcpy的行为未定义。所以目标空间必须足够大,确保能放入源字符串。
例:
3.模拟实现strcpy
char* my_strcpy(char* dest,const char* src)
{
char* ret=dest;//把目的地地址存起来,以防下面计算时变化找不到原来地址
assert(dest&&src);//保证指针的有效性,使用时记得引用<assert.h>头文件
//while (*src != '\0')
//{
// *dest = *src;
// dest++;
// src++;
//}
//*dest = *src;//拷贝'\0'
while((*dest++ = *src++))//上面和这里的实现是一样的
{
;
}
return ret;
}
--------------------------------------------------------------------------------------------------------------------------------
-
strcat 字符串追加函数
char * strcat ( char * destination, const char * source );
1.目标空间可修改且必须足够大,能容纳下源字符串内容,源字符串(source指针指向的字符串)必须以'\0'结束
2.strcat函数将source追加到dest,并用空字符终止结果字符串。source的第一个字符覆盖dest的终止空字符(即'\0')。追加字符串时不执行溢出检查。如果源字符串和目标字符串重叠,则strcat的行为未定义。
例:
3.模拟实现strcat
char* my_strcat(char* dest, const char*src)
{
char*ret = dest;//把目的地地址存起来,以防下面计算时变化找不到原来地址
assert(dest&&src);//保证指针的有效性,使用时记得引用<assert.h>头文件
while (*dest)//先找到目的地的'\0'
{
dest++;
}
while ((*dest++ = *src++))//追加过去
{
;
}
return ret;
}
--------------------------------------------------------------------------------------------------------------------------------
-
strcmp 字符串比较函数
int strcmp ( const char * str1, const char * str2 );
strcmp函数不是比较字符串长度,是比较字符串字符的ASCII值,并返回一个值,指示它们之间的关系。
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字;
例:
模拟实现strcmp:
int my_strcmp(const char*str1, const char*str2)
{
assert(str1&&str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;//str1大于或者小于str2的时候返回他们的差值
}
———————————————————————————————————————————
-
长度受限制的字符串函数
-
strncpy 字符串复制函数
char * strncpy ( char * dest, const char * source, size_t num );
strncpy函数将source的初始计数字符复制到dest并返回dest。如果num小于或等于source的长度,则不会自动将空字符('\0')追加到复制的字符串中。如果num大于source的长度,则目标字符串将补0,补足num个。如果源字符串和目标字符串重叠,则strncpy的行为未定义。
例:
模拟实现strncpy:
#include <stdio.h>
char* my_strncpy(char*dest,const char*source,size_t num)
{
char *ret = dest;
while (num && (*dest++ = *source++))//复制
num--;
if (num) //用零填充
while (--num)
*dest++ = '\0';
return ret;
}
-------------------------------------------------------------------------------------------------------------------------------
-
strncat 字符串追加函数
char * strncat ( char * dest, const char * source, size_t num ); strncat函数将source的初始字加上终止的null字符追加到dest终止空字符。如果在追加计数字符之前,source中出现空字符,strncat将追加source中的所有字符,直至空字符。如果num大于source的长度,则使用source的长度代替num(不足目标长度时不会补0)。结果字符串以空字符结尾。如果复制发生在重叠的字符串之间,则行为未定义。例:
模拟实现strncat:
#include<stdio.h>
char* my_strncat(char* dest,const char* source,size_t num)
{
char *ret = dest;
while (*dest++)
{
;
}
dest--;
while (num--)
{
if (!(*dest++ = *source++))
return ret;
}
*dest = '\0';
return ret;
}
-------------------------------------------------------------------------------------------------------------------------------
-
strncmp 字符串比较函数
int strncmp ( const char * str1, const char * str2, size_t num );
strncmp函数按ASCII比较str1和str2中的num个字符,并返回一个值,该值指示子字符串之间的关系。strncmp是_strnicmp的一个区分大小写的版本。
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字;
例:
模拟实现strncmp:
int my_strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1&&str2);//保证指针的有效性,使用时记得引用<assert.h>头文件
while (num > 0)
{
if (*str1 > *str2)
{
return *str1-*str2;//str1大于或者小于str2的时候返回他们的差值
}
else if (*str1 < *str2)
{
return *str1 - *str2;//str1大于或者小于str2的时候返回他们的差值
}
else if (*str1 == *str2)
{
str1++;
str2++;
num--;
}
else
{
str1++;
str2++;
num--;
}
}
return 0;
}
———————————————————————————————————————————
-
字符串查找函数
-
strstr
const char * strstr ( const char * str1, const char * str2 );
str2为要查找的字符串,str1为查找目的地,找到了就返回指向str1中第一个出现的str2的指针,如果str不是str1的一部分,则返回空指针。匹配过程不包括终止的空字符,但会在此停止。
例:
模拟实现strstr:
char* my_strstr(const char*str1, const char*str2)
{
assert(str1&&str2);
char* cp = (char*)str1;
char* substr = (char*)str2;
char* s1 = NULL;
if (*str2 == '\0')
return NULL;
while (*cp)
{
s1 = cp;
substr = str2;
while (*s1&&*substr && (*s1 == *substr))
{
s1++;
substr++;
}
if (*substr == '\0')
return cp;
cp++;
}
}
-------------------------------------------------------------------------------------------------------------------------------
-
strtok
char * strtok ( char * str, const char * sep ); sep参数是个字符串,定义了用作分隔符的字符合集,第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针(strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。) strtok函数的第一个参数不为NULL,函数将找到str中的第一个标记,strtok函数将保存它在字符串中的位置。 strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。如果字符串中不存在更多标记,则返回NULL指针。
例:
-
错误信息报告
-
strerror 错误信息报告函数
char * strerror ( int errnum ); 这个函数是把错误码转换成错误信息,每个数字都有自己的错误信息,strerror可以帮我们把信息翻译出来,使用时记得包含<errno.h>
例:
-
perror 错误信息打印函数
void perror ( const char * str );
这个函数首先把错误码转化为错误信息然后打印错误信息(包含了自定义信息)如图:
———————————————————————————————————————————
-
内存操作函数
-
memcpy 内存复制函数
void * memcpy ( void * destination, const void * source, size_t num );
将num个字节从源指向的位置直接复制到目标指向的内存块。该函数不检查源中是否有任何终止的空字符,它总是精确复制num字节。为避免溢出,目标和源参数指向的数组大小应至少为num字节,且不应重叠(对于重叠的内存块,memmove是一种更安全的方法)
模拟实现:
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest&&src);
void* ret = dest;
while (num--)
{
*(char*)dest = *(char*)src;//转化为char*比较方便
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
-
memmove 内存移动函数
void * memmove ( void * destination, const void * source, size_t num ); 将num个字节从源指向的位置复制到目标指向的内存块。复制就像使用了中间缓冲区一样进行,允许目标和源重叠。该函数不检查源中是否有任何终止的空字符-它总是精确复制num字节。为避免溢出,目标和源参数所指向的数组的大小应至少为num字节。
模拟实现:
void * memmove(void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count)) {
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else {
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return ret;
}
-
memset 初始化内存函数
void * memset ( void * ptr, int value, size_t num );
将ptr指向的内存块的首个num字节设置为value。memset() 函数常用于内存空间初始化。
如:
char str[100];
memset(str,0,100);
模拟实现:
void*my_memset(void*str, int val, size_t num)
{
assert(str);
void*p = str;
while (num--)
{
*(int*)str = val;
str = (int*)str + 1;
}
return p;
}
-
memcmp 内存比较函数
int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 将ptr1指向的内存块的第一个num字节与ptr2指向的第一个num字节进行比较,如果它们都匹配,则返回零;如果不匹配,则返回一个不同于零的值,ptr1<ptr2返回小于0的值,反之返回大于0的值。 注意,与strcmp不同,函数在找到空字符后不会停止比较。
模拟实现:
int my_memcmp(const void*ptr1,const void*ptr2, size_t num)
{
assert(ptr1);//记得使用assert头文件
assert(ptr2);
while (num--)
{
if (*(char*)ptr1 == *(char*)ptr2)
{
ptr1 = (char*)ptr1 + 1;
ptr2 = (char*)ptr2 + 1;
}
else
{
if (*(char*)ptr1 > *(char*)ptr2)
{
return 1;
}
else
{
return -1;
}
}
}
return 0;
}