字符串和内存函数

字符串和内存函数

#include<stdio.h>
#include<string.h>

int main()
{
  //char a = "0";
  char arr[] = "abcdef";
  char arr1[] = {'a','b','c','d','e','f'};
  char arr2[] = {'a','b','c','d','e','f''\0'};
  char arr3[10] = {'a','b','c','d','e','f'};
  int len = strlen(arr);//string length   6
  int len = strlen(arr1); //未知大小       随机值
  int len = strlen(arr2); //6
  i0nt len = strlen(arr3);//后面初始化为0    \0的ASCII值为0
  return 0;
}

strlen-字符串长度

字符串是以‘\0’为结束标志的

返回是size_t,是为无符号数。

//计数器
size_t my_strlen(const char* str)
{
  	int count = 0;
	while(*str != '\0')  
    {
      count++;
      str++;
    }
  	return count;
}
size_t my_strlen1(const char* str)
{
  if(*str!='\0')
    return my_strlen1(str+1) +1
  if(*str == "\0") 
  	return 0
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr); 
	printf("%d\n",len);
	return 0;
}

strcpy-字符串拷贝

char* strcpy(char* destination,const char * source);
  • 源字符串必须以‘\0’结束
  • 会将源字符串中的’\0’拷贝到目标空间
  • 目标空间必须足够大,能够放下源字符串
  • 目标空间必须可变
  • 学会模拟实现
  • strcpy函数返回的是目标空间的起始地址 ,目的在于可以达到链式访问
int mian()
{
  char arr1[20] = {0};
  //char* arr1 ="qwertyiop"   会崩溃,目标空间是常量字符串
  char arr2[] = "abcdef";
  strcpy(arr1,arr2);  //原字符串必须有\0`
  
  printf("%s\n",arr1);  //abcdef
  return 0;
}
char* my_strlen(char* dest,const  char* src)
{  
  	assert(dest != NULL && src != NULL) //断言一下,有空的直接报错
    char* ret = dest;
  	while(*src != '\0')
 	{
   		*dest++ = *src++;
 	}
    *dest = *src;// \0
    return ret
}
char* my_strlen1(char* dest,const  char* src)
{  
  	assert(dest != NULL && src != NULL); //断言一下,有空的直接报错
  	char* ret =dest;
    while(*dest++ = *src++)
 	{
   		;
 	}
    return ret;
}

int mian()
{
  char arr1[20] = {0};
  char* arr2 = "hello bit";
  my_strcpy(arr1,arr2);
  printf("%d\n",arr1);
}

strcat

char* strcat(char * destination ,const char* source)
  • 源字符串与目标字符串都需要\0
  • 目标空间必须足够大,能够放得下源字符串
  • 目标空间可以修改
  • 不可以自己给自己追加
char* strcat(char* dest;const char* src)
{
  assert (dest && src);
  char* ret = dest
  while(*dest)
  {
    dest++;
  }
  while(*dest++ = *src++)
 {
   		;
 }
  return ret;
}
int main()
{
  cahr arr1[20] = 'hello';
  char arr2[] = ' bit';
  strcat(arr1,arr2);
  my_strcat(arr1,arr2)
  printf("%s\n",arr1);//hello bit
  
  return 0;
}

strcmp

strcmp函数比较的不是字符串的长度,而是比较字符串中对应字符的大小,如果相同,就比较下一对,直到遇到不同或者遇到\0。

int my_strcmp(const char* s1,const char* s2)
{
  assert (s1 && s2);
  while(*s1 == *s2)
  {
    if(*s1 =='\0')
    {
      return 0;//相等
    }
    s1++;
    s2++;
  }
  // 不相等
  if (*s1>*s2)
    return 1;
  else
    return -1;
}
int my_strcmp1(const char* s1,const char* s2)
{
  assert (s1 && s2);
  while(*s1 == *s2)
  {
    if(*s1 =='\0')
    {
      return 0;//相等
    }
    s1++;
    s2++;
  }
  // 不相等
  return *s1 - *s2
}
int main()
{
  char arr1[] = "abc";
  char arr2[] = "abc";
  int ret == strcmp(arr1,arr2);
  if(ret >0)
  {
    printf(">\n");
  }
  else if(ret == 0)
  {
    printf("==\n");
  }
  else
  {
  	printf("<\n");
  }
}

strcpy,strcat,strcmp:长度不受限制的字符串函数。

int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "qwertyuiop";
  
  strcpy(arr1,arr2);//errf
}

strncpy,strncat,strncmp:长度受限制的字符串长度

strstr

char * strstr(const char* str1,const char* str2);
  • str2是否是str1的子串
  • 如果找到返回第一次出现的地址,找不到就是空指针
char* my_strstr(char* str1,char* str2)
{
  assert(str1&&str2);
  char* s1 = str1;
  char* s2 = str2;
  char* cur= str1;
  while(*cur)
  {
    s1 =cur;
    s2 = str2;
    while( *s1 && *s2 && *s1 == * s2)
    {
      s1++;
      s2++;
    }
    if(*s2 == '\0')
    {
      return cur;
    }
    cur++;
  }
  return NULL;//找不到
}
int main()
{
  char arr1[] = "abcdefabcdef";
  char arr2[] = "cdef";
  char * ret = my_strstr(arr1,arr2);
  if( NULL == ret)
  {
    printf("找不到子串\n")}
  else
  {
    printf("%s\n",ret);
  }
  return 0;
}

查找子串的时候,KMP算法-B站:比特大博哥

strtok

char* strtok(char* str,const char* sep)
  • sep参数是个字符串,定义了用作分割符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或多个由sep字符串中一个或者多个分割符分割的标记
  • strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针
  • strtok会改变被操作的字符串,故一般是
  • strtok函数的第一个参数不为NULL,函数将找到同一个str中第一个标记,strtok将会保存他的位置
  • strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个位置
  • 其中包含静态变量
int main()
{
  char arr[] = "zpengwei@yeah.net";
  char buf[30] ={0};
  strcpy(buf);
  const char* sp = "@.";
  //strtok 
  //"@,"
  //zpengwei\0yeah.net
  strtok(arr,sep); //只找第一个标记
  strtok(NULL,sep);//是从保存好的位置开始继续往后找
  strtok(NULL,sep);
  return 0;
}
int main()
{
  char arr[] = "zpengwei@yeah.net";
  char buf[30] ={0};
  strcpy(buf);
  const char* sep = "@.";
  char* str = NULL;
  for(str = strtok(buf,sep);str!=NULL,str = strtok(NULL,sep))
  {
    printf("%s\n",str);
  }
}

strerror

char * strerror(int errno)

全局的变量:errno(错误码)

返回错误码,所对应的错误信息。

int main()
{
  printf("%s\n",strerror(0));
  return 0;
}
#include<errno.h>  //需要引入头文件
int main()
{
  int * p =(int*)malloc(40);//向堆区申请内存
  if (p==NULL)
  {
    //printf("%s\n",strerror(errno));
    perror("Malloc");//打印错误信息特别方便
  }
  return 0;
}
#include<ctype.h>
int main()
{
  int ret = isdigit('4');  //数字字符返回正数,非数字字符返回0
  printf("%d\n",ret); 
  int ret = islower(ch);  //都是小写返回正数,非小写字符返回0
  return 0;
}

字符串操作函数(分类\转换)

toupper/tolower:转换成大小写

内存操作函数

memcpy

void* memcpy(void* dest, const void* src,size_t count);
  • 函数memcpy从source 的位置开始向后复制num个字节到destination
  • 遇到\0不会停止
  • 内存地址有重叠,复制结果都是未定义的
my_memcpy(void* dest,void* src,size_t count)
{
  assert(dest && count);
  void* ret = dest
  while(count--)
  {
    *(char*)dest = *(char*)src;   //强制类型转换不是一直产生的
    dest = (char*)dest +1;
    src = (char*)src +1;
  }
  return ret;
}
int main()
{
  int arr[10] = {1,2,3,4,5,6,7,8,9,10};
  int arr2[5] = {0};
  my_memcpy(arr2,arr1,20);
  
  return 0;
}

memmove

void* memmove(void* dest, const void* src,size_t count);
  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
  • 如果源空间和目标空间出现重叠,就使用memmove函数处理的
void * my_memmove(void* dest,const void* src,size_t count)
{
  //dest<src 从前往后拷贝
  //dest>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);
    }
  }
  return ret;
}
int main()
{
  int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
  my_memmove(arr+2,arr,20);
}

memcmp

int memcmp(const void* dest, const void* src,size_t count)
  • 比较从ptr1和ptr2指针开始的num个字节
  • = 0 相同
  • 大于0 dest大于src
  • 小于0 dest小于src

memset

void* memset(void * dest, int ch, size_t n);

设置内存字节为指定值,memset是以字节为单位来初始化内存单元的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

love2study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值