c语言:字符串和内存函数介绍

 字符串和内存函数:



目录

1、strlen(包含于头文件string.h)

2、strcpy(包含于头文件string.h)

3、 strcat(包含于头文件string.h)

4、strcmp(包含于头文件string.h)

5、strstr (包含于头文件string.h)

6、7、8、strncpy,strncat,strncmp                ​​​​​​​        ​​​​​​​        ​​​​​​​   (均包含于string.h中)

9、strtok

10、strerror

11、常见字符分类函数(islower,isupper,isdigit等)

12、字符转换函数(tolower以及toupper)

13、memcpy函数(memmove,memcpy的重叠用法)

14、memcmp




 

1、strlen(包含于头文件string.h)

  • strlen是一种求字符串长度的函数,它的定义为
size_t strlen ( const char * str );
//引用头文件  string.h
  •  strlen的目标字符串以‘\0’作为结束标志,返回的则是'\0'之前出现的字符的个数(不包含'\0');
  • 参数(目标字符串)必须以'\0'结尾,否则就会越界读取,返回一个错误值(随机值);
  • strlen的返回类型size_t类型(无符号类型)
  • 举例:
     
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { "abcdefg" };//一共7个字符
	int ret = strlen(arr);
	printf("%d", ret);

	return 0;
}

  •  模拟实现strlen函数
    #include<stdio.h>
    int my_strlen(  char* arr)
    {
    	
    	char* end = arr;
    	while(*end++ )
    	;
    	return end - arr-1;
    }
    int main()
    {
    	char arr[] = { "abcdefgh" };
    	int len=my_strlen(arr);
    	printf("%d", len);
    
    	return 0;
    }

2、strcpy(包含于头文件string.h)

  • strcpy是一种字符串拷贝的函数,它的定义为:
char* strcpy(char * destination, const char * source );
  • strcpy将source指向的字符串拷贝到destination所指向的字符串当中;
  •  源字符串必须以 '\0' 结束; 
  • 会将源字符串中的 '\0' 拷贝到目标空间;
  • 目标空间必须足够大,以确保能存放源字符串。否则可能会造成缓冲溢出的情况;
  • 目标空间必须可变。(目标空间如果不可修改则会程序崩溃)
  • 举例
#include<stdio.h>
#include<string.h>
int main()
{
	char source[] = { "xxxx" };
	char destination[20] = { "abcdefgh" };
	strcpy(destination,source);
	printf("%s", destination);
	return 0;
}

  • 模拟实现 :
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    char* my_strcpy(char* dest, const char* str)
    {
    	assert(*dest != NULL);
    	assert(*str != NULL);
    	char* ret = dest;
    	//拷贝str指向的字符串到dest指向的空间,包含'\0'
    	while (*dest++ = *str++)
    	{
    		;
    	}
    	//返回目的空间的起始地址
    	return ret;
    }
    int main()
    {
    	char arr1[] = "abcdefghi";
    	char arr2[] = "bit";
    	my_strcpy(arr1, arr2);
    	printf("%s\n", arr1);
    	printf("%s\n", arr2);
    	return 0;
    }

3、 strcat(包含于头文件string.h)

  • strcat函数定义为:
char * strcat ( char * destination, const char * source );
  • 将source所指向的字符串追加到destination所指向的字符串后面(从destination中从左至右找到的第一个'\0'开始往后追加);
  • 源字符串必须以 '\0' 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 举例
    #include<stdio.h>
    #include<string.h>
    int main()
    {
    	char destination[20] = { "abcd" };
    	char source[] = { "xxxx" };
    	strcat(destination, source);
    	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; }

4、strcmp(包含于头文件string.h)

  •  strcmp函数定义为:
    int strcmp ( const char * str1, const char * str2 );
  •  strcmp将str2指向的字符串和str1指向的字符串从第一个开始逐个向后比较,并规定标准
    返回值对比
        字符串大小       返回值
    第一个字符串大于第二个字符串
     返回大于0的数字
    第一个字符串等于第二个字符串
     返回0
    第一个字符串小于第二个字符串
     返回小于0的数字
  • 举例:例如字符串"abcd"
          和 "abce" 由于'e'>'d',则第二个字符串>第一个字符串,返回小于0的数字 
            "abdd"
            "abce" 由于'd'>'c',则第一个字符串>第二个字符串,返回大于0的数字
  •  模拟strcmp函数:
    #include<stdio.h>
    
    int my_strcmp(char* arr, char* crr)
    {
    	while (*arr && *crr)
    	{
    		if (*arr == *crr)
    		{
    			arr++;crr++;
    		}
    		else if (*arr > *crr)
    			return 1;
    		else 
    			return -1;
    	}
    	if (*crr == '\0' && *arr == '\0')
    		return 0;
    	else if (*crr = '\0')
    		return 1;
    	else
    		return -1;
    }
    int main()
    {
    	char arr[] = { "abce" };
    	char crr[] = { "abce" };
    	int ret = my_strcmp(arr, crr);
    	printf("%d", ret);
    	return 0;
    }

5、strstr (包含于头文件string.h)

  • strstr函数定义为
char * strstr ( const char *str1, const char * str2);
  •  strstr用于找到str1所指向的字符串中第一次出现str2所指向的字符串的地址
  • 举例:
    #include<stdio.h>
    int main()
    {
    char arr[]={"abcdefabcdef"};
    char brr[]={"bcd"};
    char* p=strstr(arr,brr);
    return 0;
    }
  • 模拟实现:
    #include<stdio.h>
    char* my_strstr( char* str1, char* str2)
    {
    	
    	
    	if (*str2 == '\0')
    		return str1;
    
    	while (*str1)
    	{   char* p = str1;
    	    char* crr = str2;
    		while (*crr == *p)
    		{
    			p++;
    			crr++;
    		}
    		if (*crr == '\0')
    			return str1;
    		str1++;
    	}
    	return (NULL);
    }
    int main()
    {
    	char arr[] = { "abcdefbbcdef" };
    	char crr[] = { "cde" };
    	char* p = my_strstr(arr, crr);
    	printf("%c", *p);
    	return 0;
    }

6、7、8、strncpy,strncat,strncmp(均包含于string.h中)

 区别于strcpy,strcat,strcmp,他们之间多了一个n,这个n就用于固定要访问的字符串长度。

在不讨论返回值的情况下,他们都有一个固定的格式 
strn ***(char*destination,char*source,int n)

  • strncpy,固定从source所指向的字符串当中拷贝从第一个字符开始,长度为n的字符串到destination所指向的字符串当中。
  • strncat,将source所指向的字符串的前n个字符追加到destination所指向的字符串当中(覆盖掉destination指向的字符串末尾的

        '\0')。如果n大于字符串长度,则会追加全部字符。

  • strncmp,比较两个字符串的前n个字符,比较方法不变。

9、strtok

  • strtok 函数定义

    char * strtok ( char * str, const char * sep );
  • sep所指向的字符串,定义了在str中当作分割符的字符集合,strtok函数通过sep找到str中的分隔符,将其标记并改为
    '\0',然后返回这个标记的指针。(strtok函数会改变str所指向的字符串,所以参数一般都是目标字符串的临时拷贝)
  • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置
  • strtok函数第一参数若为空指针,函数将在同一个字符串中被保存的位置开始,查找下一个分隔符并标记返回该标记所指向的下一个元素的指针。
  • 举例:
    #include<stdio.h>
    #include<string.h>
    int main()
    {
    	char arr[] = { "xx?abc{ddf+ll" };
    	char* p = arr;
    	char sep[] = { "?{+" };
    	char*ret=strtok(p, sep);
    	printf("%s\n", ret);
    	ret = strtok(NULL, sep);
    	printf("%s\n", ret);
    	ret = strtok(NULL, sep);
    	printf("%s\n", ret);
    	return 0;
    }
    结果可见,strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。如果找不到,则返回空NULL指针。(如果这里第四次调用,已经被分割完,则会返回空指针)。

10、strerror

  •  返回错误码,所对应的错误信息(必须包含头文件string.h,stdio.h,与errno.h)
  • strerror函数定义为
      errnum为错误码,不同的错误码对应着不同的错误信息;当错误信息生成的时候就会被保存在errnum当中,识别errnum当中的错误码信息就可以查找解决对应的问题。
    char * strerror ( int errnum );
  •  演示:
    #include<errno.h>
    #include<string.h>
    #include<stdio.h>
    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));
    return 0;
    }

11、常见字符分类函数(islower,isupper,isdigit等)

  • 举例,就拿isdigit函数来说,此类函数包含于头文件ctype.h中;当判断为是数字字符时,isdigit函数返回非0的数字,当判断为非数字字符的时候,返回数字0;
    #include<stdio.h>
    #include<ctype.h>
    int main()
    {
    
    	char ch = 'a';
    	int flag = isdigit(ch);
    	if (flag)
    		printf("YES\n");
    	else
    		printf("NO\n");  //打印结果为NO;
    		return 0;
    }

一些其他的分类函数(表格);返回值和类型与上述相当;

isdigit判断是否为0~9的十进制数字
isxdigit判断是否为十六进制(包含十进制和大小写字母)
islower判断是否为小写字母
isupper判断是否为大写字母
isalpha判断是否为大小写字母
isalnum判断是否为字母或者数字
ispunct判断是否为标点符号已经任何数字或字母的图形字符
isgraph判断是否为任何图形字符
isprint判断是否为任何可打印字符(包括图形和空白字符)

12、字符转换函数(tolower以及toupper)

  • 函数定义为:

    int tolower ( int c );
    int toupper ( int c );
  • 使用:(此处将返回值改为大写,并未转变原字符串)
    #include <stdio.h>
    #include <ctype.h>
    int main ()
    {
      int i=0;
      char str[]="abcdef ABCDEF.\n";
      char c;
      while (str[i])
     {
        c=str[i];
        if (isupper(c)) 
            c=tolower(c);
        putchar (c);
        i++;
     }
      return 0;
    }

     

13、memcpy函数(memmove,memcpy的重叠用法)

  • 函数定义为:
     
void * memcpy ( void * destination, const void * source, size_t num );
  • 函数memcpysource的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来。
  • 如果sourcedestination有任何的重叠,复制的结果都是未定义的。
  • 举例:(其他类型的数据同样如此)
    #include<stdio.h>
    #include<string.h>
    int main()
    {
    	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    	int brr[10] = {0};
    	memcpy(brr, arr, 20);
    	//这里将arr的前五个元素拷贝到brr中;
    	for (int i = 0;i < 10;i++)
    		printf("%d ", brr[i]);
    	return 0;
    }

  • 模拟实现memcpy(同时也是memmove的实现):
    #include<stdio.h>
    
    void* my_memcpy(void *dest, void *str, size_t n)
    {
    	void* ret = dest;
    	if (dest < str)
    	{
    		while (n--)
    		{
    			*(char*)dest = *(char*)str;
    			dest = (char*)dest + 1;
    			str = (char*)str + 1;
    
    		}
    	}
    	else
    	{
    		
    		while (n--)
    		{
    			*((char*)dest + n) = *((char*)str + n);
    			
    		}
    	}
    	return ret;
    }
    
    
    int main()
    {
    	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    	int brr[5] = { 0 };
    	my_memcpy(arr+2, arr, 20);
    	for (int i = 0;i < 10;i++)
    	{
    		printf("%d ", arr[i]);
    	}
    	return 0;
    }

14、memcmp

  • memcmp函数定义 :
    int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  •  类似于strcmp,这里num来控制两个字符串比较的长度(单位字节),返回值类似于strcmp。
    str1   ? str2      返回值
          >      >0
          <      <0
          =      =0

  • 举例:
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        int str1[] =    { 1,2,3,4,5,6,7 };
        int str2[] =    { 1,2,3,4,7,6,6 };
       int ret= memcmp(str1, str2,20 );
    
       if (ret > 0)
           printf("str1>str2\n");
       else if (ret < 0)
           printf("str1<str2\n");
       else
           printf("str1=str2\n");
        return 0;
    }
    //运行结果为 str1 < str2

     
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值