首页 > 其他分享 >你真的了解c语言的10大字符串函数吗?

你真的了解c语言的10大字符串函数吗?

时间:2024-03-20 19:33:31浏览次数:26  
标签:10 return 函数 int str1 char dest 字符串


乐观学习,乐观生活,才能不断前进啊!!!

我的主页:optimistic_chen
我的专栏:c语言
点击主页:optimistic_chen专栏:c语言
创作不易,大佬们点赞鼓励下吧~

前言:

长度不受限制的字符串函数-strcpy,strcat,strcmp
长度受限制的字符串函数-strncpy,strncat,strncmp

文章目录

1.strlen函数(计算字符串长度)


总结:
• 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯ 出现的字符个数(不包含 ‘\0’ )。

• 参数指向的字符串必须要以 ‘\0’ 结束。

• 注意函数的返回值为size_t,是⽆符号的( 易错 )

• strlen的使⽤需要包含头⽂件#include<string.h>

直接使用库函数:

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

int main ()
{
  char szInput[256];
  printf ("Enter a sentence: ");
  gets (szInput);
  printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));
  return 0;
}


自主模拟:

test 1:

//计数器⽅式
int my_strlen(const char * arr)
{
int count = 0;
assert(arr);//断言确定字符串不为空
while(*arr)
{
count++;
arr++;
}
return count;
}

test 2:

//递归解决问题
int my_strlen(const char * arr)
{
assert(arr);//断言确定字符串不为空
if(*arr == '\0')
return 0;
else
return 1+my_strlen(arr+1);
}

test 3:

//指针-指针的⽅式
int my_strlen(char *s)
{
assert(arr);
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;//指针之间的大小==字符串个数
}

2. strcpy函数(拷贝字符串)


总结:
• 源字符串必须以 ‘\0’ 结束。
• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间。
• ⽬标空间必须⾜够⼤以确保能存放源字符串。
• ⽬标空间必须可修改。

直接使用库函数

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

int main ()
{
  char str1[]="Sample string";
  char str2[40];
  char str3[40];
  strcpy (str2,str1);
  strcpy (str3,"copy successful");
  printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
  return 0;
}

在这里插入图片描述

自主模拟

test 1:

my_strcpy(char* dest, char* src)
{
	while (*src != '\0')
	{
		*dest++ = *src++;
	}
	*dest = *src;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };

	my_strcpy(arr2, arr1);

	printf("%s\n", arr2);
	return 0;
}

test 2:

char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))
     {
       ;
     }
return ret;//返回目的地
}

3.strcat函数(字符串追加)


总结:
• 源字符串必须以 ‘\0’ 结束。
• ⽬标字符串中也得有‘\0’ ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。

直接使用库函数

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

int main ()
{
  char str[80];
  strcpy (str,"these ");
  strcat (str,"strings ");
  strcat (str,"are ");
  strcat (str,"concatenated.");
  puts (str);
  return 0;
}

自主模拟

test 1:

char* my_strcat(char* dest,const char* src)
{
	char ret = dest;
	while (*dest != '\0')
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[30] = "hello ";
	char arr2[30] = "reader";
	my_strcat(arr1, arr2);
	printf("%s", arr1);
}

4.strcmp函数(两个字符串比较)


总结:
◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
◦ 第⼀个字符串等于第⼆个字符串,则返回0
◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
◦ 那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。

直接使用库函数

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

自主模拟

test 1:


int my_strcmp(char* str1, char* str2)
{
	assert(str1 && str2);

	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}
int main()
{
	char arr1[] = "abd";
	char arr2[] = "acfed";
	int ret = my_strcmp(arr1, arr2);
	printf("%d", ret);
	return 0;
}

5.strncpy函数(有限制的拷贝字符串)


总结:
• 拷⻉num个字符从源字符串到⽬标空间。
• 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

直接使用库函数

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

int main ()
{
  char str1[]= "To be or not to be";
  char str2[40];
  char str3[40];

  /* copy to sized buffer (overflow safe): */
  strncpy ( str2, str1, sizeof(str2) );

  /* partial copy (only 5 chars): */
  strncpy ( str3, str2, 5 );
  str3[5] = '\0';   /* null character manually added */

  puts (str1);
  puts (str2);
  puts (str3);

  return 0;
}

自主模拟

test 1:

char* my_strncpy( char* dest,const char* src, int n)
{
	int i = 0;
	for (i = 0; src[i] != '\0'&&i<n; i++)
	{
		dest[i] = src[i];
	}
	dest[i] = '\0';
	return dest;
}
int main()
{
	char dest[100] = "acdef";
	char* src = "acd";
	char* ret=my_strncpy(dest, src, 3);
	printf("%s", ret);
	return 0;
}

6.strncat函数(有限制的追加字符串)


总结:
•将source指向字符串的前num个字符追加到destination指向的字符串末尾,追加⼀个 \0 字符
•如果source指向的字符串的⻓度⼩于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾

直接使用库函数

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

自主模拟

test 1:

char* my_strncat(char* dest, char* src, size_t num)
{
	char ret = dest;
	while (*dest != '\0')
	{
		dest++;
	}
	while (num&&(*dest++ = *src++)!='\0')
	{
		num--;
	}
	*dest = '\0';//追加结束后结尾
	return ret;
	
}
int main()
{
	char arr1[20] = "hello ";
	char arr2[20] = "reader";
	my_strncat(arr1, arr2, 4);
	printf("%s", arr1);
	return 0;
}

实现结果:
在这里插入图片描述

7. strncmp函数(有限制比较字符串)

在这里插入图片描述
总结:
⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟
如果提前发现不⼀样,就提前结束,⼤的字符所在的字符串⼤于另外个。
如果num个字符都相等,就是相等返回0.

直接使用库函数

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

自主模拟

test 1:

int my_strncmp(char* str1, char* str2,size_t num)
{
	int ret = 0;
	while (num--!=0)
	{
		ret = *str1 - *str2;
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	return ret;
}
int main()
{
	char arr1[] = "apple";
	char arr2[] = "acpbe";
	int ret = my_strncmp(arr1, arr2, 4);
	printf("%d", ret);
	return 0;
}

在这里插入图片描述

8.strstr函数(查找相同的字符串)


总结:
函数返回字符串str2在字符串str1中第⼀次出现的位置
字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志

直接使用库函数

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

自主模拟

test 1:

char* my_strstr(char* str1, char* str2)
{
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* sta = str1;
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	while (*sta)
	{
		s1 = sta;
		s2 = str2;
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return (char*)sta;
		sta++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "acdefgh";
	char arr2[] = "fgh";
	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("找不到\n");
	}
	else
	{
		printf("%s", ret);
	}
	return 0;
}

在这里插入图片描述

9.strtok函数(分割字符串)


总结:
• sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合
• 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记。
• strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容并且可修改。)
• strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。
• strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。
• 如果字符串中不存在更多的标记,则返回 NULL 指针。

直接使用库函数


int main()
{
	char arr[] = "[email protected]";
	char arr2[30] = { 0 };
	strcpy(arr2,arr);
	const char* sep = "@.";
	char* ret = NULL;
	for (ret = strtok(arr, sep); ret != NULL; ret = strtok(NULL, sep))
	{
		printf("%s\n",ret);
	}
	return 0;
}

10.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));
  return 0;
}

在这里插入图片描述

完结

本次博客到此结束,博主认为大家需要熟练掌握前8种函数,能够独立自主实现函数。
最后觉得博客有帮助,可以点点关注,支持一下,期待下次博客~~~

标签:10,return,函数,int,str1,char,dest,字符串
From: https://blog.csdn.net/optimistic_chen/article/details/136790631

相关文章

  • 字符串函数
    这些字符串函数一定加头文件#include<string.h>strlen函数:1.它的功能:计算字符串的长度 2.strlen的实现:intmy_strlen(constchar*str){intcount=0;assert(str);while(*str){count++;str++;}returncount;}strcut函数:1.这个函数实现的是字......
  • NOJ南邮上机 矩阵变换问题 PROB1020 Python
    PROB1020   矩阵变换问题描述:给定一个 n×m的矩阵,对于 初始矩阵 中所有值为 1 的元素,重置其 所在行列 的所有元素为 0,最后输出整个修改后的矩阵。输入:输入共包含 1+n行。第一行包两个整数 n 和 m,分别表示矩阵的长和宽,题目保证 2≤n,m≤700且 4≤n×m......
  • SQL窗口函数
    通俗易懂的学会:SQL窗口函数-知乎(zhihu.com)SQL题目讲解——窗口函数(一)_哔哩哔哩_bilibili因为窗口函数是对where或者groupby子句处理后的结果进行操作,所以窗口函数原则上只能写在select子句中  ......
  • 复试C++14真题 看程序写结果5 虚函数、继承 易错?
    复试C++14真题 看程序写结果5  虚函数、继承#include<iostream>usingnamespacestd;classA{public:virtualvoidprint(){cout<<"A::print"<<endl;}//voidprint(){cout<<"A::print"<<endl;}};classB:public......
  • Java中常见字符串拼接九种方式
    一、前言在Java编程中,字符串拼接是一项非常基础的操作,它涉及到了很多日常开发工作中常见的场景,例如拼接SQL语句、构建HTTP请求参数等等。因此,对于掌握好字符串拼接技巧不仅有助于提高代码效率,而且能够避免一些潜在的性能问题。下面我们就来列举出来几种方式,搭配例子!二......
  • opengl日记10-opengl使用多个纹理示例
    文章目录环境代码CMakeLists.txt文件内容不变。fragmentShaderSource.fsvertexShaderSource.vsmain.cpp总结环境系统:ubuntu20.04opengl版本:4.6glfw版本:3.3glad版本:4.6cmake版本:3.16.3gcc版本:10.3.0在<opengl学习日记9-opengl使用纹理示例>的基础上,拓展使用多个纹......
  • w10下安装mysql8.0及dbeaver24记录
    1、首先到官网或者下载网站,下载mysql8.0的安装包,本次是从第三方下载网站下载的msi安装包,直接点开安装就行2、安装完后,参考https://blog.csdn.net/Javachichi/article/details/1327585513、然后下载安装dbeaver,安装好后配置连接mysql,其中自动下载mysql驱动时可能会报错,提示maven......
  • CF1091F 题解
    blog。提供线性做法,各方面完爆反悔贪心。先钦定能不飞就不飞,最后再分配盈余的能量。可能会在飞Lava的时候不够能量,只需要在前面来回移动,刷能量即可。由于Swim比Walk快,所以能Swim就全部用Swim刷能量,不能就Walk。最后是分配盈余能量。显然优先把Walk换成Fly,换一......
  • Android第一行代码——快速入门 Kotlin 编程(3.7 Kotlin课堂:标准函数和静态方法)
    目录3.7        Kotlin课堂:标准函数和静态方法3.7.1    标准函数with、run和apply3.7        Kotlin课堂:标准函数和静态方法        现在我们即将进入本书首次的Kotlin课堂,之后的几乎每一章中都会有这样一个环节。虽说目前你已经可......
  • 10大漏洞评估和渗透测试工具【附安装包】
    1、NetsparkerSecurityScanner专为企业设计的强大的漏洞扫描和管理工具,它可以检测和利用SQL注入和XSS等漏洞。https://www.netsparker.com/product/2、AcunetixScanner针对中小型企业的Web应用程序漏洞扫描程序,但也可以扩展到更大的组织。它可以检测SQL注入......