常用字符函数和字符串函数的最简单明了的讲解和代码演示

求字符串长度:

strlen:

在这里插入图片描述
注意事项:

  1. 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
  2. 参数指向的字符串必须要以 ‘\0’ 结束。
  3. 注意函数的返回值为size_t,是无符号的
#include <stdio.h> 
int main() 
{
    
        const char*str1 = "abcdef";
     const char*str2 = "bbb";    
    if(strlen(str2)-strlen(str1)>0)    
    {
    
           
     printf("str2>str1\n");    
    }    
     else    
     {
    
            
     printf("srt1>str2\n");    
     }   
      return 0; 
}

模拟实现strlen的三种方法:

//计数器方式 
int my_strlen(const char * str) 
{
    
      
   int count = 0;  
   while(*str)  
 {
    
       
   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(char *s)
{
    
            
   char *p = s;        
   while(*p != ‘\0)               
   p++;        
   return p-s; 
}

- 长度不受限制的字符串函数

strcpy

在这里插入图片描述
注意事项:

  1. 源字符串必须以 ‘\0’ 结束。

  2. 会将源字符串中的 ‘\0’ 拷贝到目标空间。

  3. 目标空间必须足够大,以确保能存放源字符串。

  4. 目标空间必须可变

//模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
    
    
	assert(dest != NULL);
	assert(src != NULL);
	char*ret = dest;
	while (*dest++ = *src++)//拷贝字符串 包括\0
	{
    
    
		;
	}
	return  ret; //返回的是目标空间的起始地址
}
int main()
{
    
    
	char arr1[20] = "***********";
	char arr2[] = "nice guy";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
    return 0;
}

strcat

在这里插入图片描述
注意事项:

  1. 源字符串必须以 ‘\0’ 结束
  2. 目标空间必须有足够的大,能容纳下源字符串的内容。
  3. 目标空间必须可修改。
//模拟实现strcat 字符追加
#include<stdio.h>
#include<assert.h>
char* my_strcat(char*dest,const char*src)
{
    
    
	assert(dest&&src != NULL);
	char *ret = dest;
	while (*dest) 
	{
    
    
		dest++;
	}
	while (*dest++ = *src++)
	{
    
    
		;
	}
	return ret;
}
int main()
{
    
    
	char arr1[20] = "good ";
	char arr2[] = "guy";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

strcmp

在这里插入图片描述
标准规定:

第1个字符串 > 第2个字符串, return大于0的数字
第1个字符串 = 第2个字符串, return 0
第1个字符串 < 第2个字符串, return 小于0的数字

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char*s1, const char*s2)
{
    
    
	assert(*s1 && *s2 != NULL);
	while (*s1 == *s2)
	{
    
    
		if (*s1 == '\0')
			return 0;
		s1++;
		s2++;
	}
	return *s1 - *s2;
}
int main()
{
    
    
	/*char *p = "abcdef";*/
	//int ret = strcmp("cd", "abcd");
	int ret = strcmp("abcd", "cd");
	//int ret = strcmp("abcd", "abcd");
	/*int ret = my_strcmp("acd", "abcdef");*/
	printf("%d\n", ret);
	return 0;
}

**

- 长度受限制的字符串函数介绍

strncpy

在这里插入图片描述
注意事项:

  1. 拷贝n 个字符从源字符串到目标空间。
    如果源字符串的长度<n 则拷贝完源字符串之后,在目标的后边追加0,直到n个
strncpy
#include<stdio.h>
#include<assert.h>
char* my_strncpy(char*dest, const char*src)
{
    
    
	assert(*dest&&*src);
		char * cp = dest;
	while (*cp)
	{
    
    
		cp++;
	}
	while (*cp++ = *src++)
	{
    
    
		;
	}
	return dest;
}
int main()
{
    
    
	char arr1[20] = "*******";
	char arr2[] = "abc";
	my_strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);
	return 0;
}

strncat

在字符串的结尾追加n个字符。

在这里插入图片描述

#include <stdio.h> 
#include <string.h>
int main () 
{
    
      
char str1[20];  
char str2[20];  
strcpy (str1,"To be ");  
strcpy (str2,"or not to be");  
strncat (str1, str2, 6);  
puts (str1);  return 0; 
}

strncmp

在这里插入图片描述

#include <stdio.h> 
#include <string.h>
int main () 
{
    
      
     char str[][5] = {
    
     "R2D2" , "C3PO" , "R2A6" };  
     int n;  
     puts ("Looking for R2 astromech droids...");  
   for (n=0 ; n<3 ; n++)  
     if (strncmp (str[n],"R2xx",2) == 0)  
{
    
        
     printf ("found %s\n",str[n]);  
}  
     return 0; 
}

- 字符串查找

strstr
在这里插入图片描述

#include <stdio.h> 
#include <string.h>
int main () 
{
    
      
    char str[] ="This is a simple string";  
    char * pch;  pch = strstr (str,"simple");  
    strncpy (pch,"sample",6);  
    puts (str);  
    return 0;
 } 

strtok
在这里插入图片描述
注意事项:

  1. sep参数是个字符串,定义了用作分隔符的字符集合
  2. 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  3. strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
  4. strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  5. strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  6. 如果字符串中不存在更多的标记,则返回 NULL 指针
#include <stdio.h> 
#include <string.h>
int main () 
{
    
      
    char str[] ="- This, a sample string.";  
    char * pch;  
    printf ("Splitting string \"%s\" into tokens:\n",str);  
    pch = strtok (str," ,.-");  
     while (pch != NULL) 
 {
    
       
     printf ("%s\n",pch);    
     pch = strtok (NULL, " ,.-"); 
 }  
    return 0; 
   }

- 错误信息报告

strerror
在这里插入图片描述
返回错误码,所对应的错误信息。

#include <stdio.h> 
#include <string.h> 
#include <errno.h>//必须包含的头文件 
int main () 
{
    
       
   FILE * pFile;   
   pFile = fopen ("unexist.ent","r");   
   if (pFile == NULL)     
    printf ("Error opening file unexist.ent: %s\n",strerror(errno));     
    //errno: Last error number   return 0; 
} 
 

- 字符操作

- 内存操作函数

memcpy

在这里插入图片描述
注意事项

  1. 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  2. 这个函数在遇到 ‘\0’ 的时候并不会停下来。
  3. 如果source和destination有任何的重叠,复制的结果都是未定义的
#include <stdio.h> 
#include <string.h> 
 
struct 
{
    
       
   char name[40];   
   int age; 
} person, person_copy; 
 
int main () 
{
    
       
   char myname[] = "Pierre de Fermat"; 
   memcpy ( person.name, myname, strlen(myname)+1 );   
   person.age = 46; 
   memcpy ( &person_copy, &person, sizeof(person) ); 
   printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age ); 
 
  return 0; 
  } 
//模拟实现
void * memcpy ( void * dst, const void * src, size_t count) 
 {
    
             
   void * ret = dst;   
   assert(dst);      
   assert(src);              
    while (count--) 
  {
    
                    
     *(char *)dst = *(char *)src;                
      dst = (char *)dst + 1;                
       src = (char *)src + 1;        
   } 
 
        return(ret); 
 } 

memmove

在这里插入图片描述
注意事项

  1. 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  2. 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
#include <stdio.h> 
#include <string.h> 
 
int main () 
 {
    
       
   char str[] = "memmove hahahahahahah yes";  
   memmove (str+20,str+15,11);   
   puts (str);   
   return 0; 
  } 
 
//模拟实现
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); 
        
}

memcmp

在这里插入图片描述
比较从ptr1和ptr2指针开始的num个字节

#include <stdio.h> 
#include <string.h> 
 
int main () 
{
    
       
   char buffer1[] = "DWgaOtP12df0";  
   char buffer2[] = "DWGAOTP12DF0"; 
   int n; 
   n=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; 
}

猜你喜欢

转载自blog.csdn.net/weixin_47721582/article/details/114326348