当前位置: 首页 > news >正文

字符数组和字符串

字符数组:

char 类型的数组,用来存储多个字符(代表字符串),由于char占的内存比较小(1个字节),所以存储多维数组的时候建议使用,比较省内存。

  • char类型是存储不了中文的
  • 中文占2个字节

字符数组声明:

字符数组声明就是简单的数组声明

char c[100];//一维数组
char c1[10][10];//二维数组
char c2[10][10][10];//三维数组

字符数组初始化:

C/C++标准库中的字符串处理函数(如strcpystrlenprintf等)均依赖\0来判断字符串的结束。若字符串未以\0结尾,这些函数会继续读取内存,直到遇到随机内存中的\0,可能导致程序崩溃或数据错误。

需要注意的字符数组存储数据的时候需要添加 '\0' 代表字符串的结束

  • 由于需要存储'\0' 所以数组能存储的数据个数需要-1,留一个位置
  • 未以\0结尾的字符数组可能被误认为字符串,导致函数越界访问内存。
  • 初始化时如果你没给'\0'系统会自动添加

初始化的三种方式:

  • 使用字符串进行初始化: "内容"
  • 使用大括号+单个字符的方式初始化: {'字符1','字符2','字符3','字符4'.....}
  • 使用大括号+字符串的方式初始化:{“字符串”}
#include<iostream>
using namespace std;
int main()
{//字符串的结束标志为'\0',所以数组要多开一个空间存放'\0'//存放满数据,三种初始化方式相同 char a[10]="123456789";//只能存放9个数,第十个存放'\0' char b[10]={'1','2','3','4','5','6','7','8','9'};char c[10]={"123456789"};char d[]="12345";//自动添加\0//或者末尾手动直接添加\0 char d[10]={'1','2','3','4','5','6','7','8','9','\0'};return 0; 	
} 

数据不够时使用'\0'填充:

#include<iostream>
using namespace std;
int main()
{//未存放满数据,会用'\0'补齐 char e[10]="12345";for(int i=0;i<10;i++){if(e[i]=='\0') cout<<"\\0"<<endl; else cout<<e[i]<<endl;	} return 0; 	
} 

memset()初始化:

头文件:#include<cstring>函数:

memset(数组,值,数组大小);

  • 第一个参数:数组名
  • 第二个参数:任何字符
  • 第三个参数:获取数组的内存大小  sizeof(数组名)
  • 初始化是按照字节进行初始化,所以要获取数组内存
  • 如果你只初始化了数组的一部分,其他未初始化的部分为可能为SOH,所以使用的时候尽量进行数据全覆盖(但最好留一个位置存储\0)
#include<iostream>
#include<cstring>
using namespace std;
int main()
{char c[10];memset(c,'A',sizeof(c)-1);//留一个\0的位置for(int i=0;i<10;i++){if(c[i]=='\0') cout<<"\\0"<<endl; else cout<<c[i]<<endl;	} cout<<c[9]<<endl;return 0; 	
} 

fill()初始化:

头文件:#include<algorithm>函数:

fill(起点,终点,值);

  • char arr[10];
  • 起点为:arr   终点:arr+9   9为数组长度留一个\0
  • 第一个参数:数组的起始位置   可以使用+num 进行后移
  • 第二个参数:数组的终点位置   也可以移动结束位置
  • 第三个参数:可以为任和的值
  • 如果你只初始化了数组的一部分,其他未初始化的部分为可能为SOH,所以使用的时候尽量进行数据全覆盖(但最好留一个位置存储\0)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{char c[10];fill(c,c+9,'A');//留一个\0的位置 for(int i=0;i<10;i++){if(c[i]=='\0') cout<<"\\0"<<endl; else cout<<c[i]<<endl;	} cout<<c[9]<<endl;return 0; 	
} 

字符数组赋值:

  • 使用数组[下标]=进行单个字符赋值
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{char c[10]="123";c[0]='A';//赋值 c[8]='D';//赋值 for(int i=0;i<10;i++){if(c[i]=='\0') cout<<"\\0"<<endl; else cout<<c[i]<<endl;	} return 0; 	
} 

使用for循环进行赋值

#include<iostream>
using namespace std;
int main()
{char c[10]="123";int i=0;for(char c1='0';c1<'9';c1++,i++){//循环进行赋值c[i]=c1;}for(int i=0;i<10;i++){if(c[i]=='\0') cout<<"\\0"<<endl; else cout<<c[i]<<endl;	} return 0; 	
} 

不能使用=进行数组和数组间的赋值,因为数组名是一个地址

#include<iostream>
#include<cstring>
using namespace std;
int main()
{char c[10];char d[10]="456";c=d;//报错,不能用=进行赋值c="123456";//报错,也不能用字符串去进行赋值  return 0; 	
} 

获取长度

字符数组长度:

由于char类型只占一个字节,直接使用sizeof(数组名)就是数组长度。

#include<iostream>
using namespace std;
int main()
{char c[10]="123";cout<<"字符数组长度:"<<sizeof(c);return 0; 	
} 

字符串长度:

由于\0代表结束,使用循环直接读到\0停止即可获取字符串长度

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{char c[10]="123";int num=0;for(;c[num]!='\0';num++){}//读取字符长度cout<<num;return 0; 	
} 

使用系统函数获取字符串长度

  • 头文件#include<ctsring>
  • strlen(字符数组名)
  • 可以获取到第一个'\0'前的元素个数
#include<iostream>
#include<cstring>
using namespace std;
int main()
{char c[10]="123";cout<<strlen(c)<<endl;//获取字符串长度 return 0; 	
} 

字符数组的输入和输出:

字符数组输入:

使用方法说明
cin>>字符数组名不能读取空格(空格和回车代表结束)
cin.getline(字符数组名,字符个数)   读取一行数据可以读取空格
cin.get()读取一个字符
scanf("%s",字符数组名)C语言方法头文件#include<cstdio>不能读取空格
fgets(字符数组名,字符个数,stdin)C语言方法头文件#include<cstdio>可以读取空格

字符数组的输出:

使用方法说明
cout<<字符数组名直接输出字符串
printf("%s",字符数组名)C语言方法头文件#include<cstdio>直接输出字符串
puts(字符数组名)C语言方法头文件#include<cstdio>直接输出字符串
#include<iostream>
#include<cstdio>
using namespace std;int main()
{ char a[10];//C语言方式的读取和输出(不能读取空格)scanf("%s",a);//输入 printf("%s\n",a); //输出 //C语言方式读取一行(可以读取空格)char b[10]; fgets(b,9,stdin);//输入puts(b);//输出 //C++输入和输出(不能读取空格)cin>>b;cout<<b<<endl;//C++读取一行(可以读取空格)cin.getline(b,9);//读取一行cout<<b<<endl; return 0; 	
} 

字符数组常用函数:

头文件:#include<cstring>

函数名函数的功能
strlen(S1)获取字符串长度,获取第一个''\0'之前的数据长度
strcpy(S1,S2)把S2复制到S1中
strcat(S1,S2)把S2连接到S1
strcmp(S1,S2)比较两者的大小 相同返回0
strchr(S1,ch)返回一个指针,指向S1中字符出现的位置
strstr(S1,S2)返回一个指针,指向字符串S1中S2第一次出现的位置
memcpy(A,B,size)把数组B中的Size个字符复制给A

strcpy(s1,s2)复制:

  • 将s2复制给s1,需要确保s1的容量大于等于s2的容量
  • 不能正确处理重叠的字符串。如果源字符串和目标字符串重叠,strcpy()的行为是未定义的。
  • 它不检查目标缓冲区的大小,如果源字符串比目标缓冲区长,可能会覆盖缓冲区并导致缓冲区溢出。这可能导致安全漏洞和其他问题。
  • 它不能正确处理源字符串中的空字符。如果源字符串包含空字符,strcpy()会在该点停止复制,即使源字符串中还有其他字符。

当S1容量小于S2时,编译器会对S1进行扩容(Dev-C++-5.11)(但不建议这样使用)

#include<iostream>
#include<cstring>
using namespace std;
int main()
{//strlen 获取'\0'之前的数据长度 char a[10]="123456";char b[5]={};//b的容量小于astrcpy(b,a);//但还是复制成功了for(auto p:b)//遍历数组{cout<<p<<endl;}cout<<"b字符串的长度"<<strlen(b)<<endl; cout<<b[6]<<endl;return 0; 	
} 

实现一个strcpy()

//size为s1数组长度 
void Strcpy(char s1[],char s2[],int size){ if(size-1<strlen(s2)) cout<<"s1容量不够"<<endl;else{for(int i=0;i<strlen(s2);i++) s1[i]=s2[i];//复制 for(int i=strlen(s2);i<size;i++) s1[i]='\0';//其他数据置为'\0' } 
}

memcpy(A,B,size)复制个数

memcpy(A,B,size):把数组B中的Size个字符复制给A

#include<iostream>
#include<cstring>
using namespace std;
int main()
{ char a[10]="123456";char b[20]="789459";memcpy(b,a,5);//把a中的5个数据复制b中 for(auto i:b){cout<<i<<endl;} return 0; 	
} 

实现memcpy()

//length s1的数组长度  size为复制的个数
void Memcpy(char s1[],char s2[],int length,int size){if(length-1<size) cout<<"s1容量不足"<<endl;else if(strlen(s2)<size) cout<<"元素个数大于s2的长度"<<endl; else{for(int i=0;i<size);i++) s1[i]=s2[i];//复制 for(int i=size;i<length;i++) s1[i]='\0';//其他数据置为'\0' } 
}

strcat(s1,s2)拼接:

strcat(s1,s2):把S2连接到S1

#include<iostream>
#include<cstring>
using namespace std;
int main()
{//strlen 获取'\0'之前的数据长度 char a[10]="123456";char b[20]="789456";cout<<strcat(b,a)<<endl;return 0; 	
} 

实现Strcat()

//size为s1的数组长度 
void Strcat(char s1[],char s2[],int size){int length=strlen(s2)+strlen(s1);//获取复制后的总长度 if(size-1<length) cout<<"s1容量不够"<<endl;else{for(int i=strlen(s1);i<length;i++) s1[i]=s2[i];//复制 for(int i=length;i<size;i++) s1[i]='\0';//其他数据置为'\0' } 
}

strcmp(s1,s2)比较:

从第一个元素开始根据ASCLL值比较两者的大小 

  • s1==s2 返回0
  • s1>s2返回1
  • s1<s2返回2
#include<iostream>
#include<cstring>
using namespace std;
int main()
{//strlen 获取'\0'之前的数据长度 char a[10]="123456";char b[20]="789456";cout<<strcmp(a,b)<<endl;//输出-1cout<<strcmp(b,a)<<endl;//输出1 return 0; 	
} 

实现strcmp()

int Strcmp(char s1[],char s2[]) 
{//获取小的数据长度int length=min(strlen(s1),strlen(s2));//开始比较for(int i=0;i<length;i++){if(s1[i]>s2[i]) return 1;else if(s1[i]<s2[i]) return -1;} //当数据都相等时,需要判断长度 if(strlen(s1)==strlen(s2)) return 0;else if(strlen(s1)>strlen(s2)) return 1;else return -1;
}

strcahr(s1,ch)查找字符

strcahr(s1,ch):查找字符,返回一个指针(char*),指向S1中字符第一次出现的位置

  • 找到返回第一次出现的位置
  • 没找到返回 nullptr 
#include<iostream>
#include<cstring>
using namespace std;
int main()
{ char a[10]="ab1cdef";char * p;p=strchr(a,'1');//返回的是第一次出现的位置cout<<*p<<endl;//输出的是当前位置的值 cout<<p<<endl;//输出的是字符串 //获取字符在字符串中的位置,可以通过计算指针与原始字符串指针的差值来得到。//输出所处的位置 cout<<p-a+1<<endl; //输出之后的数据cout<<p+1<<endl; return 0; 	
} 

实现strchr()

char *Strchr(char c[],char c1){char * p=c;//指向第一个元素while(*p!='\0'){if(*p==c1) return p;p++;}return nullptr;
}

strstr(s1,s2)查找字符串:

strstr(S1,S2)返回一个指针,指向字符串S1中S2第一次出现的位置,没找到返回nullptr

#include<iostream>
#include<cstring>
using namespace std;
int main()
{ char a[10]="ab1cdef";char b[20]="cdef";char * p;p=strstr(a,b);//返回的是第一次出现的位置//获取字符在字符串中的位置,可以通过计算指针与原始字符串指针的差值来得到。//输出所处的位置 cout<<p-a+1<<endl; return 0; 	
} 

实现strstr()

char* Strstr(char c[],char c1[]){char *p=c;if(strlen(c1)>strlen(c)) return nullptr;for(int i=0;i<=strlen(c)-strlen(c1);i++){bool b=true;//表示是否匹配成功 for(int j=i,k=0;j<i+strlen(c1)&&k<strlen(c1);j++,k++){if(c[j]!=c1[k]) {b=false;break;}}if(b) return p+i;}return nullptr; 
} 

string字符串:

C++ 标准库提供了 string 类类型,string是一个类,固定占用28个字节,string没有'\0'

  • 头文件:#include<string>
  • 关键词:string
  • 内部也是由char数组实现的
  • 但可以自动扩容

string声明:

把string 当作正常的数据类型使用即可

  • 格式   string 变量名
string str;//正常创建即可

string初始化:

直接使用 " "对字符串进行初始化

string str="ssssssssss";//初始化

string赋值:

字符串和字符串之间可以用 = 进行赋值

string s1="abcdefghijklmnopq";
string s2=s1;//可以使用=进行赋值

string数据访问:

使用数组的方式进行访问:  字符串名[下标]  进行字符的修改和访问

string s1="ABCDEFGHIJKL";
cout<<s1[0];//输出第一个字符
s1[0]='K';//修改你一个字符

string字符串拼接:

使用 + 进行拼接

  • 可以拼接字符
  • 也可以拼接字符串
	string s1="ABCDE";s1+='C'; //拼接字符string s2="KKKKKKKK";s1+=s2;//拼接字符串s1+="PPPPPPP"; cout<<s1<<endl; 

string中的函数:

函数名描述
size() length()返回字符串长度cout<<str.size()/length();
empty()判断是否为空cout<<str.empty();
operator[]使用[ ]访问字符串中指定位置的字符。cout<<str[1];
find()查找子字符串在字符串中的位置。 string::nops 代表查找失败cout<<str.find("abc");
rfind()从后往前查找子字符串在字符串中的位置cout<<str.rfind("abc");
at()访问字符串中指定位置的字符(带边界检查)std::cout << str.at(0);
substr()返回从指定位置开始的子字符串。string sub = str.substr(0, 5);
append()在字符串末尾添加内容。str.append(" more");
insert()在指定位置插入内容。str.insert(pos, "inserted");
erase()删除指定位置的字符或子字符串。str.erase(pos, length);
clear()清空字符串。str.clear();
compare()比较两个字符串。(按照ASCLL比较,从头开始比较,直到那个数比较大即可退出)int result = str.compare("other");
c_str()返回 C 风格的字符串(以 null 结尾)const char* cstr = str.c_str();

string数据类型转换:

string和int:

说明使用方法
string 转 int std::stoi()函数
int 转 stringto_string() 函数

#include<iostream>
#include<string>
using namespace std;
int main()
{//string 转 intstring a="123456";int b=stoi(a);cout<<b<<endl;//int 转 stringint num = 123;string str = to_string(num);cout << str;return 0; 	
} 

函数的实现:

//string 转 int 
int string_int(string s){ //字符串转数字 小于2e9 int num=0;//拆解累加 for(int i=0;i<s.size();i++) num=num*10+(s[i]-'0');return num;
} 
//int 转 string 
string int_string(int n){//拆解逆转string str;while(n!=0){str+='0'+n%10;n/=10;} string s1;for(int i=str.size()-1;i>=0;i--)s1+=str[i];//逆转拼接 return s1 ;
}

char数组和int:

说明使用方法
char数组 转 int使用#include <cstdlib>下的 std::atoi()函数
int 转 char数组

使用 #include<cstdlib>下的

std::char itoa(int value, char* string, int radix); radix为进制数


#include <iostream>
#include <cstdlib>
using namespace std;
int main() {//char数组 转 int 类型char str[] = "456";int num = std::atoi(str);std::cout << "num = " << num;////int类型 转 char数组int a=123456789;char c[20];itoa(a,c,10);cout<<c<<endl;return 0;
}

函数的实现:

//char 转 int
int  char_int(char c[]){//结果在int范围内 int num=0;//拆解累加 for(int i=0;i<strlen(c);i++) num=num*10+(c[i]-'0');return num;
} //int 转 char*
//radix的范围为2-10 超过十的就不判断了 
void int_char(int num,char c[],int radix,int length){ //首先先用strig先存储数据,看一下结果的长度string s;while(num!=0){s+='0'+num%radix;num/=radix;}if(s.size()<=length-1){ //数据可以放得下,把数据放入int j=0;//c数组下标 for(int i=s.size())-1;i>=0;i--,j++) c[j]=s[i];for(int i=j;j<length;j++) c[i]='\0';//把剩余位置都设置为\0 }else{cout<<"数组容量不够"<<endl;}
}

string输入和输出

字符串输入:

使用方法说明
cin>>字符串名不能读取空格(空格和回车代表结束)
getline(cin,字符串名)   读取一行数据可以读取空格
  • getline (istream& is, string& str, char delim); 读到delim截止

  •  getline (istream& is, string& str);

字符串输出:

使用方法说明
cout<<字符串名直接输出字符串
使用循环进行输出访问每一个数据
#include<iostream>
#include<string>
using namespace std;int main()
{ string s;cin>>s;//读取不带空格的数据cout<<s<<endl;//读取带空格的数据getline(cin,s);//读取一行数据string s1;getline(cin,s1,'p');//读取一行读到p停止cout<<s<<endl<<s1<<endl; return 0; 	
} 

C++处理带空格的字符串:

当我们要处理带空格的字符串的时候是有很多种方法解决的

  • 字符数组的读取方法
  • 字符串的读取方法

字符数组的读取方法:

使用方法说明
cin.getline(字符数组名,字符个数)   读取一行数据可以读取空格
cin.get()读取一个字符(可读取空格)
fgets(字符数组名,字符个数,stdin)C语言方法头文件#include<cstdio>可以读取空格

需要注意的是 使用过cin后  \n 没有被cin读取,所以还会残留在输入流中,需要将 \n 读取掉再读取一行

单独读取一行:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{char a[50];fgets(a,sizeof(a),stdin);//需要指定数据长度,更安全cout<<a<<endl;return 0;
}

连续输入读取:

//连续输入和读取多行
#include<iostream>
#include<cstdio>
#include<cstdlib> //char数组转int 的头文件
using namespace std;
int main()
{char n[50];//创建一个字符串fgets(n,sizeof(n),stdin);//读取需要输入的字符串个数int N=atoi(n);//转换为数字 为数据的行数while(N--){gets(n);//输入字符串cout<<n<<endl; //输出字符串}return 0;
}

处理cin输入问题:

//连续输入和读取多行
#include<iostream>
#include<cstdio>
#include<cstdlib> //char数组转int 的头文件
using namespace std;
int main()
{char n[50];//创建一个字符串int N=0;cin>>N//读取行数 cin.get();//读取掉 \n //后面就能正常读取一行数据了 while(N--){gets(n);//输入字符串cout<<n<<endl; //输出字符串}return 0;
}

字符串的读取方式:

使用getline函数读取一行带空格的数据

  • getline (istream& is, string& str, char delim); 读到delim截止

  •  getline (istream& is, string& str);

单独读取一行:

//读取一行数据
#include<iostream>
#include<string>
using namespace std;
int main()
{string s;getline(cin,s);//读取一行数据cout<<s<<endl; return 0;
}

连续输入读取:

//输入和输出多行数据时
#include<iostream>
#include<string>
using namespace std;
int main()
{string s;getline(cin,s);//输入读取的个数int N=stoi(s);//转换为整数while(N--){getline(cin,s);cout<<s<<"--------------"<<endl; } return 0;
}

处理cin输入问题:

//当使用cin输入数据时,一定cin读取的那行的回车符号先去除掉
#include<iostream>
#include<string>
using namespace std;
int main()
{int N=0;string s;cin>>N;//把这行全部读取完 ,不然cin这行的\n 会被留在输入流中的   getline()读取 getline(cin,s);//或者使用cin.get() 读取掉这个回车符while(N--){getline(cin,s);cout<<s<<"--------------"<<endl; } return 0;
}

http://www.dtcms.com/a/473772.html

相关文章:

  • 【TIDE DIARY 3】dify: chatflow; docker: exec
  • Docker Compose学习
  • 从iBizPMS到iBizPLM:一场研发管理平台的四年级架构革命
  • KingbaseES SQL Server模式扩展属性管理:三大存储过程实战指南
  • 5118网站怎么做的登录贵州省住房和城乡建设厅网站
  • 开源 C++ QT QML 开发(十六)进程--共享内存
  • 密码学系列 - 零知识证明(ZKP) - MSM运算
  • 厦门网站制作推广友链是什么
  • 大的网站建设公司好赣州章贡区最新招聘信息
  • 总结Vue.js等成功项目的生态建设经验
  • 西安北郊网站开发wordpress上传附件
  • mysql读写分离中间件——Atlas详解
  • jndi使用druid,在tomcat中配置druid监控
  • tomcat 默认编码的设置
  • 【mybatisPlus详解】
  • 回归与分类算法全解析:从理论到实践
  • 什么是 Qt 的元对象系统?
  • 【LeetCode】68. 文本左右对齐
  • 第十九周周报
  • Springboot 常见面试题汇总
  • 驻马店市做网站百度收录软件
  • 在实际项目中,Java 应用的性能瓶颈通常出现在哪些方面,又该如何有效地进行优化?
  • 08_Freqtrade配置与开发环境
  • C++实例
  • 复习总结最终版:Linux驱动
  • Python全栈(基础篇)——Day09:后端内容(列表生成式+生成器+迭代器+实战演示+每日一题)
  • kanass入门到实战(18) - 如何通过仪表盘,快速直观掌握项目进度及度量
  • seo网站优化工具大全wordpress 百度地图api
  • webstorm 调试时不能连接网页
  • 互助网站建设公司网页制作 主流软件