c语言字符串和字符函数

1.什么是字符串 ?

字符串或串(String)是由数字、字母、下划线组成的一串字符。一般记为 s=“a1a2···an”(n>=0)。它是编程语言中表示文本的一种数据类型。

2.字符串函数的好处

C语言中对字符和字符串的处理很是频繁, 但是c语言它本身没有字符串类型,字符串通常放在常量字符串中或者字符串数组中。 字符串常量适用那些对它不做修改的字符串函数。

3. 字符串函数功能介绍与函数的模拟实现

3.1 strlen

size_t strlen ( const char * str );

功能介绍:

  • 字符串以‘\0’ 作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数(并不包括’\0‘)。
  • 参数str只想的字符串必须要以’\0‘ 结束。
  • 函数的返回值是size_t , 是无符号的(易错)。

针对易错, 我们来做这样一道题目。请问结果输出什么?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
   char* str1 = "abcdef";
   char* str2 = "bbb";
   printf("%d ", strlen(str1));
   if (strlen(str2) - strlen(str1) > 0)
   {
   	printf("str2>str1\n");
   }
   else
   {
   	printf("str1>str2\n");
   }
   return 0;
}

相信很多人都会不加思索,回答 str1的长度肯定大于 str2,所以一定输出str1>str2 。当然这样的回答也一定是错的 。
strlen函数的设计者设计strlen函数时,只是想到字符串的长度怎么可能为负数呢?故将它的返回值设置为size_t(无符号整形)。strlen(str1) 与 strlen(str2)返回的结果都是无符号的,它们加减乘除的结果当然也是无符号整形, strlen(str1) - strlen(str2) 的结果是 -4 ,在内存中的补码是oxFFFFFFFC,被当做一个无符号整形,故是一个非常大的正数,在判断条件作为真,故打印str2 > str1 。

那如何模拟实现strlen函数呢?
这里有三种实现方式,仅供参考。

方式一(设置一个计数器)

size_t mystrlen(const char* str)
{
	size_t count = 0 ; 
	while(*str)
	{
		count ++ ;
		str ++ ;
	}
	return count ;
}
		 

方法二(递归,不需设置一个临时计数器)

size_t mystrlen(const char* str)
{
	if(*str == '\0') return 0 ; 
	
	return mystrlen(str+1) + 1 ;
}

方法三(指针 - 指针)

size_t mystrlen(const char * str) 
{
	char* end  = str ; 
	while(*end)
	{
		end++;
	}
	return end - str ;
}

3.2 strcpy

char * strcpy ( char * destination, const char * source );

功能介绍:

  • 将源所指向的C字符串复制到目标所指向的字符数组中,包括结束的空字符(并在该点停止)。
  • 为了避免溢出,destination指向的数组长度应该足够长,以包含与source相同的C字符串(包括结束的’\0‘字符),并且在内存中不应该与source重叠。
  • 目标空间必须可修改。

根据以上几点, 我们注意到源字符必须以 ’\0’ 结束。
如何模拟实现 ?

供参考:

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

3.3 strcmp

int strcmp ( const char * str1, const char * str2 );

功能介绍:

  • strcmp函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下一字符对,直到字符对不相等或达到结束的空字符为止。

返回值描述:
在这里插入图片描述

实例 :

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

int main ()
{
  char key[] = "apple";
  char buffer[80];
  do {
     printf ("Guess my favorite fruit? ");
     fflush (stdout);
     scanf ("%79s",buffer);
  } while (strcmp (key,buffer) != 0);
  puts ("Correct answer!");
  return 0;
}

在这里插入图片描述
模拟实现

int mystrcmp(const char* str1 , const char* str2 )
{
	assert(str1 && str2 );
	while(*str1 == *str2)
	{
		if(*str2 == '\0') return 0 ; 
		str1 ++ , str2 ++ ;
	}
	return *str1 - *str2 ; 	
}

3.4 strcat

char * strcat ( char * destination, const char * source );

功能介绍:

  • 将源字符串的副本追加到目标字符串。目标中的结束空字符被源的第一个字符覆盖,并且一个空字符包含在目标中由两者连接形成的新字符串的末尾。
  • 目的内存空间和源内存空间不应重叠。(否则会造成死循环)

由以上几点,可知

  • 源字符串必须以‘\0’结束 。
  • 目标空间必须足够大,能够容的下源字符的内容。
  • 目标空间必须可修改。

模拟实现

char * mystrcat (char* des, const char* src )
{

    char* ret = des ;
    while(*des)des++;//找到目的字符串的结束'\0'
    while(*src)
    {
        *des = *src ;
        des++, src++;
    }
    return ret ;
}

3.5 strncpy

char * strncpy ( char * destination, const char * source, size_t num );

功能介绍:

  • 从源的第一个字符启复制到目标空间。如果在复制num个字符之前提前找到源字符串的末尾(‘\0’),则用‘\0’填充目标空间,直到向目标空间写入num个字符的总数。

简单的就以下几点:

  • 拷贝num个字符串从源字符串到目标空间。
  • 如果源字符串的长度小于num, 则拷贝完源字符串之后, 在目标的后面追加上‘\0’,知道num个。

模拟实现

char* mystrncpy(char* des , const char* src ,size_t num)
{
	char * ret = des ; 
	while (num && (*des++ = *src++) != '\0') num--;
	if(num)
		{
			while(--num)
				*des++ = '\0';
		}
	return ret ;
} 

3.6 strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

功能介绍

  • 将C字符串str1的num字符与C字符串str2的num字符比较。

  • 这个函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用以下字符对,直到字符不相等,直到到达结束的空字符,或直到num字符在两个字符串中匹配,以先出现的为准.。

模拟实现

int mystrncmp ( const char * str1, const char * str2, size_t num )
{
    while(num-- && *str1 == *str2)
    {
        if(*str2 == '\0'){
            return 0;
        }
        str1 ++ , str2 ++ ;
    }
    if(num == 0){
        return 0 ;
    }
    else 
    {
        return *str1 - *str2 ;
    }
}

3.7 strncat

char * strncat ( char * destination, const char * source, size_t num );

功能介绍:

  • 将源的第一个num字符附加到目标空间的结束字符‘\0’,再加上一个结束空字符。
  • 如果源文件中的C字符串的长度小于num,则只复制终止空字符之前的内容。

模拟实现:

char * mystrncat ( char * des, const char * src, size_t num )
{
    char * ret = des   ;
    while(*des) des++;
    while(num--)
    {
        if((*des++ = *src++) == 0)
            return ret;
    }
    *des = '\0';
    return ret ;
}

3.8 strstr

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

功能介绍

  • strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。

Example

/* strstr example */
#include <stdio.h>
#include <string.h>

int main ()
{
     char str[] ="This is a simple string";
     char * pch;
     pch = strstr (str,"simple");
     if (pch != NULL)
       strncpy (pch,"sample",6);
     puts (str);
     return 0;
}

This example searches for the “simple” substring in str and replaces that word for “sample”.

模拟实现:

	char* mystrstr(const char* str1 , const char* str2)
{
    assert(str1 && str2);
    char* s1 = NULL;
    char* s2 = NULL;
    char* cp = (char*) str1 ;
    for (; *cp != '\0'; cp++) {
        s1 = cp;
        s2 = (char*)str2;
        while(*s2 && *s1 && *s2 == *s1)
        {
            s2++,s1++;
        }
        if(*s2 == '\0'){
            return cp;
        }

    }
    return NULL;
}

4. 总结

以上就是关于字符串函数的重要知识点总结, 谢谢大家观看。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值