C++库函数(字符串)

鉴于c++语法和函数众多,希望可以熟悉掌握库函数的用法,以助于提升自己的编程能力和学习水平。主要依托 cplusplus 网站,这是一个非常好的C++学习网站,有语言的一些概念,便于理解。还有读者论坛便于讨论,不过是英文的网站,大家可以用浏览器的翻译功能进行阅读,同时也可以提高自己的英文水平。
这一篇主要是对< cstring >头文件的函数进行学习

< cstring >

一.复制

1.memmove

不同的编码里,字符和字节的对应关系也不同,与编码方式有关
一个英文占一个字节 一个中文占两个字节
先看一个引例

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[]="wang x y";
	cout<<s<<endl;
	cout<<"s[0]="<<s[0]<<endl;//s[0]=w 
	cout<<"s[1]="<<s[1]<<endl;//s[1]=a
	cout<<"s[4]="<<s[4]<<endl;//s[4]=' '
	cout<<"s+2="<<s+2<<endl;//从第三个开始ng x y 
	cout<<"sizeof(s)="<<sizeof(s)<<endl;//求字节数组后面默认/0 
	cout<<"strlen(s)="<<strlen(s)<<endl; //求长度 有几个就是几 
	return 0;
 } 

memmove用于拷贝字节,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。
该函数不检查源代码中的任何终止空字符——它总是精确地复制num字节。 为了避免溢出,由目标和源参数指向的数组的大小至少应为num字节。

函数原型:void * memmove ( void * destination, const void * source, size_t num );
有三个参数 void *destination 指向要复制内容的目标数组的指针
const void * source 指向要复制的数据源的指针
size_t num 要复制的字节数。 size_t是一个无符号整型。

举个例子:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[] = "wang xin yue";
	char b[] = "WANG XIN YUE";
	memmove(s+5, b+5, 3);//替换中间的字符
	memmove(s,"bbbb",4);//也可以
	//b+5是要复制的数组开始的地方  
	//3是复制的字节大小 s+5是目标数组被复制过来代替的地方
	cout << s << endl;
	return 0;
}

再看一个自身操作的例子

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	//char s[] = "wang xin yue";如果这样写的化会出错 溢出
	char s[30] = "wang xin yue";
	//对自己进行操作 想实现xin--wang
	memmove(s + 8, s + 7, 5);
	//这步后变成wang xinn yue 目的是拉长一位
	cout << s << endl;
	memmove(s + 5, s, 4);
	//再把前四位替换掉中间四位
	cout << s << endl;
	return 0;
}

举个汉字的例子

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	
	char s[] = "王 wang";
	//memmove(s, s + 3, 2); 结果wa wang
	memmove(s + 5, s, 2);
	cout << s << endl;//王 wa王
	return 0;
}

string类的例子

#include<iostream>
using namespace std;
int main()
{
	string s = "wang xin yue";
	string S = "WANG";
	memmove(&s[0], &S[0], 4);
	cout << s << endl;
	return 0;
}

指针指向数组例子

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[] = "wang nb";
	char* w = s;//指向字符的指针
	memmove(w,w+5,2 );
	cout << *w << endl;//解引用 第一个字符
	cout << w << endl;//nbng nb
	return 0;
}

整型数组的例子

#include<iostream>
using namespace std;
int main()
{
	int a[] = {1,2,3};
	int b[] = { 6,7,8 };
	
	cout << "a[1]=" << a[1] << endl;// 2
	cout << "sizeof(a)=" << sizeof(a) << endl;//int型占4个字节
	cout << a << endl;//a[]是一个整型数组 直接输出是首地址
	cout <<& a[1] <<"     "<< & a[2] << endl;//可见相邻元素之间地址差一个类型所占字节数
	memmove(a+1, b+1, 8);//注意此处第三个参数应是int型字节数
	for (int i = 0; i < sizeof(a)/4; i++)//直接输出不能实现 用循环
	{
		cout << a[i];
	}
	return 0;
}
2.memcpy

此函数用法和作用与memmove几乎相同但是memmove相对安全,因为memcpy会有内存重叠问题

内存重叠就是:拷贝的目的地址在源地址的范围内,有重叠。

函数原型:void * memcpy ( void * destination, const void * source, size_t num );
看一个例子 与memmove差不多

#include<iostream>
using namespace std;
class person {
public:
	char name[20];
	int age = 12;
};
int main()
{   
	person A,B;

	char s[] = "wang xin yue";
	char b[20];
	
	memcpy(A.name, s, strlen(s)+1);
	//A对象name赋值
	memcpy(B.name,A.name ,sizeof(A.name));
	//用A.name给B.name赋值
	//sizeof(A)会提示A.name可读20字节 
	//但可能从A.name中读取24字节 给B.name时可能溢出 写入24字节
	//memcpy(&B, &A, sizeof(A));//这样也可以
	cout << B.name << endl;
	char m[] = "aaaa";
	char n[]="  b";
	char c[] = "\0 c";
	memcpy(c, m, 1);
	cout << c<< endl;
	return 0;
}

二.串联

1.strcat

连接字符串 将源字符串的副本追加到目标字符串。目标中的终止空字符被源中的第一个字符覆盖,空字符包含在由目标中的两个字符串联而成的新字符串的末尾。 目的地和来源不应重叠。
函数原型:char * strcat ( char * destination, const char * source );
例:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[80] = "wang xin yue ";//[]上所占大小 会有接上字符串后溢出的情况
	char b[] = "xiao sha sha !";
	strcat_s(s, "xiao sha sha!");//strcat会报错建议使用strcat_s
	//strcat_s(s, b); 同样的效果
	string a= "WANG xin yue ";
	string c = "Xiao sha sha";
	cout<<a+c<<endl;
	cout << s << endl;
	return 0;
}
2.strncat

将源的前num个字符追加到目标,加上一个终止空字符。 如果source中字符串的长度小于num,则只复制终止空字符之前的内容。
函数原型:
char * strncat ( char * destination, const char * source, size_t num );

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[20] = "wang xin yue ";
	char b[20] = "xiao sha sha !";
	
	//strncat_s(s, b,4); 从源字符复制到目标字符 从目标字符的结尾开始 则不能改变
	strncat_s(s, b + 5, 3);//可定义开始的位置和字节长度
	
	cout << s << endl;
	return 0;
}

四.搜索

1.memchar

字符查找,在内存块中定位字符
在ptr指向的内存块的第一个num字节中搜索第一个出现的值(解释为无符号字符),并返回指向它的指针。
函数原型:
const void * memchr ( const void * ptr, int value, size_t num );
返回值为指针

字符查找例子:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	//字符查找
	char s[] = "wang sha sha";
	char* p;//返回值是一个指针 用P接收
	p =(char *)memchr(s, 'g', strlen(s));//标明返回的指针类型
	if (p != NULL)//判断返回值是否为空
		cout << "g被找到,是第"<<int(p)-int(s)+1<<"个" << endl;
	else 
		cout << "没找到" << endl;
	
	cout <<p<< endl;//此时P指向的是被查找字符g从此开始的地址
	//若查找的字节中无所找的字符 则p指向未知报错
	return 0;
}

数组查找例子:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	int s[] = { 1,2,3,4,5 };
	int * p = (int*)memchr(s, 2, sizeof(s));//要定位的值,该值作为int传递查找的是数字直接写
	
	if (p != NULL) cout << "找到了 " << p - s + 1 << endl;
	else cout << "没找到" << endl;
	
	return 0;
}

正常遍历查找,循环

#include<iostream>
using namespace std;
int main()
{
	int s[] = { 1,2,3,4,5 };
	int i;
	for (i = 0; i < 5; i++)
	{
		if (s[i] == 2)
			cout << "2找到了" << i + 1 << endl;
	}
	return 0;
}
2.strchr

定位字符串中第一个出现的字符,返回一个指针,指向字符串中第一个出现的字符。 也可以定位终止字符。
函数原型:const char * strchr ( const char * str, int character );
要定位的字符作为int提升传递,但为了比较,它在内部被转换回char。
返回值:指向字符串中第一个出现的字符的指针
举个例子:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[] = "wang xin yue xiao sha sha";
	char* p;
	p = strchr(s, 'x');
	cout << p << endl;//xin yue xiao sha sha
	while (p != NULL)
	{
		cout << "找到这个字符 " << p-s+ 1 << endl;//第一次找到此字符 指向x开始的字符串
		p = strchr(p + 1, 'x');//此时应跳过查找过的x继续查找
	}
	return 0;
}

不能是整型数组若是数组也可以定义为char类型

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[] = "12333456789";
	char* p;
	int i = 0;
	p = strchr(s,'3');
	while (p != NULL)
	{
		cout << '3' ;
		i += 1;
		p = strchr(p + 1, '3');
	}
	cout << '\n';
	cout << i << endl;
	return 0;
}
3.strcspn

找到字符串中符合条件的第一个字符,返回在第一个匹配项之前读取的字符数,如果找不到则返回字符串的长度。
函数原型:size_t strcspn ( const char * str1, const char * str2 );

#include <iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[] = "wang xin yue";
	char b[] = "mxmy";
	char c[] = "mmmm";
	int i,j;
	i = strcspn(s, b);//如果找到了返回在第一个匹配项之前读取的str1的字符数
	j = strcspn(s, c);
	cout << i << endl;
	cout << j << endl;//如果找不到返回s的长度
	cout << "第一个匹配的字符"<<s[i] <<"在这" << i + 1 << endl;
	return 0;
}
4.strpbrk

定位字符串中的字符,返回一个指针,指向str1中第一个出现的属于str2的任何字符,如果没有匹配项,则返回一个空指针。 搜索不包括字符串的终止空字符
函数原型:const char * strpbrk ( const char * str1, const char * str2 );

#include <iostream>
using namespace std;
int main()
{
	char s[] = "wang xin yue";
	char b[] = "aeiou";
	char* p;//接收返回指针
	p = strpbrk(s, b);
	cout << p << endl;
	//ang xin yue指向s中第一个出现的属于b的任何字符的指针
	cout << *p << endl;//a
	while (p != NULL)
	{
		cout << "符合条件的字符" << *p << endl;
		p = strpbrk(p + 1, b);
		//找到后再继续搜索此字符之后的字符串符合条件的字符
	}
	return 0;
}
5.strrchr

定位字符串中最后一次出现所找字符的位置
函数原型:const char * strrchr ( const char * str, int character );
指向字符串中最后出现的字符的指针。 如果找不到该字符,该函数将返回一个空指针。

#include<iostream>
using namespace std;
int main()
{
	char s[] = "wangxinyue";
	char* p = strrchr(s,'n');
	if (p != NULL)
	{
		//cout << p << endl;   nyue指向字符串中最后出现的所找字符的指针
		cout << "最后出现在" << p - s + 1 << endl;
	}
	else cout << "没有找到" << endl;
	return 0;
}

6.strspn

从第一个字符开始,搜索字符串中属于另一个字符串的字符数,若第一个不符合条件,则返回0,若符合,则到第一个不符合的字符结束。
函数原型:size_t strspn ( const char * str1, const char * str2 );

#include<iostream>
using namespace std;
int main()
{
	char s[] = "124wang xin 123 yue";
	char c[] = "4wang";
	char b[] = "123456wang";
	int i;
	int j;
	i = strspn(s, b);//从第一个开始到第一个不属于的结束
	j = strspn(s, c);//若第一个字符不属于需要的字符集则返回0
	cout << "s中属于b的有" << i << "个" << endl;//3个
	cout << "s中属于b的有" << j << "个" << endl;
	return 0;
}
7.strstr

字符串中查找字符串
返回指向str1中第一个str2的指针,如果str2不是str1的一部分,则返回空指针。 匹配过程不包括终止的空字符,但是它在那里停止。
函数原型:const char * strstr ( const char * str1, const char * str2 );

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char s[] = "WANG wang as!";
	char b[] = "wang";
	char* p = strstr(s, b);
	if (p != NULL)
	{
		memmove(p, "wwww", 4);
		cout << p << endl;
	}
	else
		cout << "没有找到" << endl;
	return 0;
}

五.其他

1.memset

在字符串中的指定字节的数中设置指定值
函数原型:void * memset ( void * ptr, int value, size_t num );

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
	char s[] = "wang sha sha";
	memset(s+1, '-', 3);//从第二个字符开始复制三个-
	//要设置的以int形式存放不能是字符串
	cout << s << endl;

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奥奖得主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值