C语言中字符串函数和字符串函数分析和实现

字符函数和字符串函数

求字符串长度 strlen
长度不受限制的字符串函数
strcpy -字符串拷贝
strcat - 字符串追加
strcmp- 字符串比较
字符串查找
strstr - 查找子字符串
strtok字符串分割
错误信息报告
strerror
字符操作
内存操作函数
memcpy
memove
memset
memcmp

函数介绍

strlen
size_t strlen(const char* str);
字符串已经’\0’作为结束标志、strlen函数返回的是在字符串中’\0’前面出现的字符个数(不包含‘\0’)。
参数指向的字符必须要以’\0’。
注意函数的返回值size_t,是无符号的。
strlen 函数的实现(3种)

size_t my_strlen(const char* str)
{	int count = 0;
	assert(str != NULL);
	while (*str != '\0')
	{
	count++;
	str++;
	}	
	return count;
}

②递归

size_t my_strlen(const char* str)
{
 assert(*str!=NULL);
  if (*str != '\0')
  {
  return 1 + my_strlen(str + 1);
  } 
  else  
  return 0;
 }`

③指针-指针

size_t my_strlen(const char* str)
{	
const char *start = str;	
while (*str != '\0')	
{		
str++;	
}	
return str - start;
}

strcpy
char* strcpy(char * destination,const char *source);
源字符串必须以’\0’ 结尾
会将字符串中的 ‘\0’ 拷贝到自己的空间
目标空间必须足够大,以确保能存放源字符串
目标空间必须可变

strcpy函数实现

char* my_strcpy(char *arr1, const char* arr2)
{	
char* ret = arr1;	
assert(arr1 != NULL);	
assert(arr2 != NULL);	
while (*(arr1++) = *(arr2++))	
{		
;	
}	
return ret;
}

strcat
char* strcat(cosnt char *str1,const char *str2);
源字符串必须以’\0’ 结尾
目标空间必须足够大,以确保能存放源字符串
目标空间必须可修改
字符串不能自己给自己追加

strcat函数的实现

char* my_strcat(char *dest, const char  *src)
{	
char*ret = dest;	
assert(dest);	
assert(src);	
while (*dest)	
{	
  dest++;	
  }	
  while (*dest++ = *src++)	
  {		
  ;	
  }
  return ret;
  }

strcmp
int strcmp(const char * str1,const char *str2);
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字

strcmp函数的实现

int my_strcmp(const char*s1, const char*s2)
{	
assert(s1);	
assert(s2);	
while (*s1 == *s2)
{	
	if (*s1 == '\0')
	return 0;		
	s1++;		
	s2++;		
	return *s1 - *s2;	
	}
}

strstr
char *strstr( const char * str1,const char * str2);

strstr 函数实现

char* my_strstr(const char*str1, const char*str2)
{	
assert(str1);
assert(str2);	
const char *s1 = str1;	
const char *s2 = str2;	
const char *cp = str1;	
if (*s2 == '\0')	
{		
return (char *)str1;	
}	
while (*cp)	
{		
s1 = cp;		
s2 = str2;		
while (*s1&&*s2&&*s1 == *s2)		
{		

s1++;		
s2++;	
}	
if (*s2 == '\0')		
{			
return (char*)cp;		
}		
cp++;	
}	
return NULL;
}

strtok
char * strtok ( char * str, const char * sep );

sep参数是个字符串,定义了用作分隔符的字符集合

第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改
变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针

memcpy
void * memcpy ( void * destination, const void * source, size_t num);

函数memcpy从src位置开始向后的num个字节复制到dst的内存位置。
这个函数遇到’\0’的时候并不会停下来。
源内存块和目标内存块重叠时,复制结果是未定义的。
memcpy函数的模拟实现

void *memcpy(void* dest, const void* src, size_t num)
{
 void* ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while (num--)
 {
  *(char* )dest = *(char*)src;
  ((char*)dest)++;
  ((char*)src)++;
 }
 return ret;
}

memmove

==void * memmove ( void * destination, const void * source, size_t num ); ==

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。

memmove函数的实现

void* my_memmove(void* dest, const void* src, size_t count)
{
 assert(dest);
 assert(src);
 if (dest < src)
 {
  //前->后
  while (count--)
  {
   *(char*)dest = *(char*)src;
   dest = (char*)dest + 1;
   src = (char*)src + 1;
  }
 }
 else
 {
  //后->前
  while (count--)
  {
   *((char*)dest + count) = *((char*)src + count);
  }
 }
}
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页