字符串函数

本文将简要介绍这些常用的C语言字符串函数,包括它们的基本功能和使用方法。通过具体的代码示例,我们将展示如何在实际编程中运用这些函数来处理字符串。

注:使用库函数里的字符串,就需要包含头文件string.h,也就是#include<string.h>

strlen函数使用及实现

 strlen - C++ 参考 (cplusplus.com)
函数声明 size_t strlen ();

主要就是求出指定字符串,或者字符串数组的元素个数,见代码:

#include<stdio.h>
#include<string.h>
int main()
{
	const char* arr = "This is string";
	printf("字符串长度为%d\n", strlen(arr));
	return 0;
}

但这个函数存在错误的使用方法,

这次的结果就跟正确的答案差太远了,是因为函数strlen的测量长度的时候碰到了‘\0’就会停下,而‘\0’就是字符数组结束标志,但在这里的数组没有'\0'符存在,strlen 函数会继续在内存中查找,直到它遇到一个偶然的零值(这可能是在其他内存位置上的),或者直到它访问到它不应该访问的内存区域(这可能导致未定义行为,如程序崩溃),就需要在最后一个字符位置加上一个'\0'。

接下来是C语言的实现:

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

这里使用了递归的方法,但是效率较低,所以存在另一个方法:

size_t our_strlen(const char* str)
{
	size_t count = 0;
	for (count = 0; *str; count++, str++)
		;
	return count;
}

用指针遍历,然后count跟着指针走,直至遇到‘\0’停止,因为‘\0’的ascll码值是0,相当于指针指向的地址存放的值不为0。strlen函数返回值是size_t,这里也采用同样的类型。

strcpy函数使用及实现

strcpy - C++ 参考 (cplusplus.com)

 是将一个字符串尽数复制到另一个指定字符串中,返回值是char*类型,但是也可以不需要接收返回值。使用结构:strcpy(char* dest ,const char* source)后者复制到前者

#include <stdio.h>  
#include <string.h> // 为了使用strcpy  
  
int main()  
{  
    char arr1[20]= "nihao hello";  
    char arr2[20] = "no helloaff";  
    char* p = arr1, *q = arr2;  
    strcpy(p,q); // 这会覆盖arr1的内容  
  
    // 打印修改后的arr1的内容  
    while (*p)  
    {  
        printf("%c",*(p++));  
    }  
    printf("\n"); 
  
    return 0;  
}

arr1中的元素都被arr2给覆盖了。但为避免溢出,指向的数组的大小应足够长,以包含与相同的 C 字符串(包括终止 null 字符),并且不应在内存重叠。

比如说

这样的结果是会出错误的 ,导致两个数组的内容都被改了。

接下来是代码的实现:

char* my_strcpy(char* det, const char* sou)//sou指针不能被改变
{
	assert(det!=NULL);//设置两个宏防止报错
	assert(sou!=NULL);//
	char* ret = det;//记录指针原来的位置
	while (( *det++=*sou++))
		;
	return ret;
}

在while语句中,执行的代码都是赋值,然后两个指针向后走,所以可以都放在判断条件中,是代码简便许多。

 比较直观的代码就是这样:

char* my_strcpy(char* det, const char* sou)
{
	char* ret = det;
	while (*sou!='\0' || *det!='\0')
	{
		*det = *sou;
		det++;
		sou++;
	}
	return ret;
}

strcat函数使用及实现

strcat - C++ 参考 (cplusplus.com)

用于连接(拼接)两个字符串,这个函数将第二个字符串(即源字符串)添加到第一个字符串(即目标字符串)的末尾,同时假设第一个字符串有足够的空间来存储结果字符串:

函数声明:char *strcat(char *dest, const char *src);
代码的使用如下:

#include <stdio.h>  
#include <string.h>  
  
int main()
 {  
    char arr1[40] = "Hello, ";   
    char arr2[] = "world!";    
    strcat(arr1, arr2);  
    // 打印连接后的字符串  
    printf("%s\n", arr1); // 输出:Hello, world!  
  
    return 0;  
}

代码实现如下:

char* our_strcat(char* dest, const char* src)
{
	char* ret = dest;
	while (*dest != '\0')
		dest++;
	while (*src != '\0')
		*dest++ = *src++;
	*dest = *src;
	return ret;
}

先让第一指针走到第一个字符串末尾,然后再追加字符串在其后,但在之前就要记录好指针的开头作为返回的值,结果就完成了。

简化了就是这样:

char* our_strcat(char* dest, const char* src)
 {
	char* ret = dest;
	assert(dest!=NULL);//设置宏防止报错
	assert(src != NULL);
	while (*dest)
		dest++;
	whlie(*dest++ = *src++)
		;
	return ret;
}

跟前面的strcpy代码有着相似的用法。

strcmp函数使用及实现

strcmp - C++ 参考 (cplusplus.com)

用于两个字符串的比较,函数格式:

int strcmp ( const char * str1, const char * str2 );
str2大于str1就返回大于0的数,如果两个字符串都相同,就返回0,如果小于就返回小于0的数。字符串的比较都是各个字符元素逐个比较,比较的是字符的ascll码值。这里就不示范使用方法了,直接实现:
int our_strcmp(const char* str1, const char* str2)
{
	while (*str1==*str2)
	{
		if (*str1 == '\0'||*str2=='\0')
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;

写一个while语句,只要两个比较元素都相同,就一直向后走,如果任一字符串到最后都一样,就返回0,如果有了不同,就跳出循环,直接返回比较结果。

  strstr函数使用及实现

strstr - C++ 参考 (cplusplus.com)

函数声明 char * strstr ( const char *str1, const char *str2 );

此函数比较两个字符串,返回str2首次出现在str1中的首位置,返回值为char*意味着返回值并不是数组下标,而是指针地址。以下是此函数的模拟实现:

char* Strstr( const char* src, const char* dest)
{
    char* s = dest;//记录dest首地址
    if (dest==NULL)//如果是空指针直接返回NULL
    {
        return NULL;//NULL值需要包含stdio.h头文集……
    }
    int c = 0;//用来计算dest指向字符串的长度,首先记为0
    while (src!='\0')//也可以写成src
    {
        if (*dest==*src)
        {
            dest++;
            src++;
            c++;          //dest指向的值与src指向的值相同,c开始计数
        }
        else
        {
            c = 0;//如果向后比较的值为开始不一样,c重新变为0,方便重新计数
            src++;
            dest = s;
        }
        if (*dest == '\0')//如果dest指向的字符串查找完成返回所需要的位置
            return src-c;
    }
    return NULL;
}

我们可以用两个指针逐一元素比较,src指针一直向后查找,如果两个指针的值开始相同,就都向后比较,如果向后不同,dest就指向起始位置,在这里我指针的值建立了一个s指针(记录dest指向字符串的首地址并且用来让dest复位的指针)和一个int类型的c变量(用来记录dest指向字符串的长度),当dest查找完成,就返回用src地址减去c值而得到的dest第一个元素出现时的地址。

如果查找到src结束都没有找到,就返回空指针就会比较合理,如果dest本身就是空指针,就返回NULL也很合理。

函数投入使用:

#include<stdio.h>
char* Strstr( const char* src, const char* dest)
{
    char* s = dest;
    if (dest==NULL)
    {
       
        return NULL;
    }
    int c = 0;
    while (src!='\0')
    {
        if (*dest==*src)
        {
            dest++;
            src++;
            c++;
        }
        else
        {
            c = 0;
            src++;
            dest = s;
        }
        if (*dest == '\0')
            return src-c;
       
    }
    return NULL;
}

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;
}

函数就是将字符串“sample”,替换其中的“simple”。

 接下来再写几个我还没有实现的字符串函数。

strncpy函数使用

strncpy - C++ 参考 (cplusplus.com)

函数的声明:

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

此函数与前面strcpy功能相同,可以看见此函数相比较于strcpy函数多了一个size_t类型参数,意思就是规定了指定长度的字符。

#include <stdio.h>  
#include <string.h>  
  
int main() 
{  
    char src[] = "Hello, world!";  
    char dest[20]; 
    // 使用 strncpy 复制最多 11 个字符(包括空字符)到 dest  
    strncpy(dest, src, 11);     
    dest[10] = '\0'; 
  
    printf("Source string: %s\n", src);  
    printf("Copied string: %s\n", dest);  
  
    return 0;  
}

如果理解了strcpy函数,那么这个函数就简单了。

strncat函数使用

同样的,此函数和strcat功能相同,但规定了使用长度。

#include <stdio.h>  
#include <string.h>  
  
int main() {  
    char dest[50] = "Hello, ";  
    char src[] = "world!";  
    size_t dest_len = strlen(dest);   
    size_t src_len = strlen(src);    
    strncat(dest, src, sizeof(dest) - dest_len - 1);   
    printf("Concatenated string: %s\n", dest);  
    return 0;  
}

strncmp函数使用

不用多说跟前两者相同的,在strncmp函数的基础上规定了指定长度,直接看代码:

#include <stdio.h>  
#include <string.h>  
  
int main() 
{  
    char str1[] = "Hello, world!";  
    char str2[] = "Hello, universe!";  
    int result = strncmp(str1, str2, 5);  
    if (result < 0) 
    {  
        printf("The %zu characters of str1 are less than str2.\n", 5);  
    } else if (result > 0) 
    {  
        printf("The %zu characters of str1 are greater than str2.\n", 5);  
    } else 
    {  
        printf("The %zu characters of str1 are equal to str2.\n",5);  
    }  
  
    return 0;  
}

此外还有一些字符分类函数:

函数名描述示例用法
isalpha()判断字符是否为字母(包括大写和小写)if (isalpha('A')) { ... }
isupper()判断字符是否为大写字母if (isupper('A')) { ... }
islower()判断字符是否为小写字母if (islower('a')) { ... }
isdigit()判断字符是否为数字(0-9)if (isdigit('5')) { ... }
isalnum()判断字符是否为字母或数字if (isalnum('a')) { ... }<br>if (isalnum('5')) { ... }
isspace()判断字符是否为空白字符(包括空格、制表符、换行符等)if (isspace(' ')) { ... }<br>if (isspace('\t')) { ... }
iscntrl()判断字符是否为控制字符(ASCII码在0-31之间,包括DEL字符)if (iscntrl('\n')) { ... }(注意:换行符不是控制字符,这里仅为示例)
ispunct()判断字符是否为标点符号if (ispunct('.')) { ... }<br>if (ispunct(',')) { ... }
isxdigit()判断字符是否为十六进制数字(0-9, A-F, a-f)if (isxdigit('A')) { ... }<br>if (isxdigit('f')) { ... }
isgraph()判断字符是否为可打印的图形字符(不包括空格)if (isgraph('+')) { ... }<br>if (isgraph('*')) { ... }
isprint()判断字符是否为可打印字符(包括空格)if (isprint(' ')) { ... }<br>if (isprint('+')) { ... }

感谢您花时间阅读我的博客。我希望通过我的分享,能够为您带来一些帮助,如果您有任何疑问、建议或想要深入讨论的话题,请在评论区留言

  • 19
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值