一、字符串
1.计算char数组本身的长度——sizeof()
示例
1 2 3 4 5 6 7 8 9 10 11 12
| char a[]="hello"; char b[]={'h','e','l','l','\0'}; char c[]={'h','e','l','l'}; cout<<sizeof(a)<<endl; cout<<sizeof(b)<<endl; cout<<sizeof(c)<<endl;
输出: 6 5 4
|
2.计算字符串的长度——strlen()
示例
1 2 3 4 5 6 7 8 9
| char a[100]="hello"; int len1=strlen(a); //strlen函数有返回值 int len2=strlen("hello"); cout<<len1<<endl; cout<<len2<<endl;
输出: 5 5
|
注意:
-
strlen仅仅是一个计数器的功能,遇到空字符串’\0’则停止计算,strlen返回第一个’\0\之前的字符长度
-
strlen只计算可见的字符,而不把空字符计算在内
-
strlen()函数返回的是储存在数组中的字符串的长度,而不是数组本身的长度
当你是在想不起来该用啥求字符串长度的时候,直接for循环也是可取的(这种方法也是遍历字符串的方法之一)
1 2 3 4 5
| char a[100]; cin>>a; int i=0; for(int i=0;a[i]!='\0';i++){} cout<<"长度为"<<i;
|
3.字符串输入输出
首先是大家最熟悉的cin和cout,要注意的是cin的使用需要附上iostream库并且加上语句 using namespace std
使用cin读入字符串只写char数组的名字就行
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include<iostream> using namespace std; char a[105],b[10][105],c[105]; int main() { cin>>a; //读入一个字符串 for(int i=1;i<=10;i++)cin>>b[i]; //读入10个字符串 cout<<a<<endl; for(int i=1;i<=10;i++)cout<<b[i]<<endl; scanf("%s",c); //scanf读入字符串和cin效果基本一样 printf("%s",c); //printf读入字符串和cout效果基本一样 return 0; }
|
要注意的是cin读入到空格或者换行符就会停止
如果要读入一整行(包括空格),请使用getline函数(还有一个get()函数,这里不统一说了,感兴趣的自己去查)
1 2 3 4 5 6 7 8 9 10 11 12
| #include<iostream> using namespace std; char a[105]; int main() { cin.getline(a,106); //第二个参数是读入长度,根据具体情况来,一般推荐设置为char数组长度+1 //如果设置读入长度大于输入长度,getline会读入到换行符并忽略换行符 //getline实际读取的字符串长度为设置的读入长度-1,因为他在读入末尾自动帮你加了个\0 cout<<a; return 0; }
|
4.字符串拼接——strcat
把字符串p和q拼起来中间再加个字符x(原始写法):
1 2 3 4 5 6 7 8 9 10
| char * mystrstr(char *p,char *q,char x) { char *tmp=new char; char *out=tmp; for(;*p!='\0';p++){*tmp=*p;tmp++;} *tmp=x;tmp++; for(;*q!='\0';q++){*tmp=*q;tmp++;} *tmp='\0'; //千万别忘了,不然会出乱码 return out; }
|
如果你懒,你可以用cstring库里的strcat函数:
strcat(S,T)函数将会把T拼接到S上,然后返回S
要注意的是这里的S和T都是char指针,如果要拼接字符上去,请在变量名前加上’&'符号
例如:
1 2 3 4
| cin>>p>>x>>q; strcat(p,&x); strcat(p,q); cout<<p;
|
说明:
strstr(T,S)是一个字符串处理函数,用于判断字符串S是否是字符串T的子串。如果是,则该函数返回S在T中首次出现的地址;否则,返回NULL。
头文件:#include <string.h>
函数原型:char *strstr(const char *str1, const char *str2);
返回值:(1) 成功找到,返回在父串中第一次出现的位置的 char *指针 (2) 若未找到,即不存在这样的子串,返回 NULL。
5.字符串复制——strcpy
函数原型:
1
| char * strcpy ( char * destination, const char * source );
|
其中distination指针指向容器字符串,source指针指向被复制的字符串
例如:
1 2 3 4 5 6 7 8 9 10 11 12
| #include <cstdio> #include <cstring> 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; }
|
输出:
1 2 3
| str1: Sample string str2: Sample string str3: copy successful
|
6.字符串查找——strstr
函数原型:
1
| char *strstr (const char *s1, const char *s2);
|
此函数返回一个指针,该指针指向s1中找到的s2的第一个字符,如果s1中不存在s2,则返回空指针。如果s2指向空字符串,则返回s1
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <cstring> #include <cstdio> int main() { char s1[] = "GeeksforGeeks"; char s2[] = "for"; char* p; p = strstr(s1, s2); if(p) { printf("String found\n"); printf("First occurrence of string '%s' in '%s' is '%s'", s2, s1, p); } else printf("String not found\n"); return 0; }
|
输出:
1 2
| String found First occurrence of string 'for' in 'GeeksforGeeks' is 'forGeeks'
|
7.字符串比较——strcmp
1
| int strcmp(const char *str1, const char *str2)
|
str1字典序小于str2时,返回值小于0
str1字典序大于str2时,返回值大于0
str1字典序等于str2时,返回值等于0
二、其他常见代码段
1.结构体排序
【例题背景】将Mystruct按score从小到大排序,若score相同则按name字典序从小到大排序
基础冒泡排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <cstdio> #include <cstring> struct Mystruct { char name[105]; int score; }a[105]; int n; int main() { scanf("%d",&n); for(int i=0;i<n;i++)scanf("%s%d",a[i].name,&a[i].score); for(int i=0;i<n;i++) for(int j=1;j<n-i;j++) if(a[j].score<a[j-1].score) { Mystruct tmp; tmp=a[j]; a[j]=a[j-1]; a[j-1]=tmp; } else if(a[j].score==a[j-1].score) { if(strcmp(a[j].name,a[j-1].name)<0) { Mystruct tmp; tmp=a[j]; a[j]=a[j-1]; a[j-1]=tmp; } } for(int i=0;i<n;i++)printf("%s %d\n",a[i].name,a[i].score); return 0; }
|
进阶sort排序(需要algorithm库)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Mystruct { char name[105]; int score; }a[105]; bool cmp(const Mystruct a,const Mystruct b) { if(a.score==b.score)return strcmp(a.name,b.name)<0; return a.score<b.score; } int n; int main() { scanf("%d",&n); for(int i=0;i<n;i++)scanf("%s%d",a[i].name,&a[i].score); sort(a,a+n,cmp); for(int i=0;i<n;i++)printf("%s %d\n",a[i].name,a[i].score); return 0; }
|
终极重载运算符(需要algorithm库)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Mystruct { char name[105]; int score; bool operator < (const Mystruct b)const{ if(score==b.score)return strcmp(name,b.name)<0; return score<b.score; } }a[105]; int n; int main() { scanf("%d",&n); for(int i=0;i<n;i++)scanf("%s%d",a[i].name,&a[i].score); sort(a,a+n); for(int i=0;i<n;i++)printf("%s %d\n",a[i].name,a[i].score); return 0; }
|
重载运算符代码通用结构:
1 2 3 4
| bool operator [你要重载的运算符] (const [比较对象的变量类型] [起个好听的变量名] )const { return [ [当前所在的结构体内的某个变量] 和 [比较对象的比较量] 的关系式 ] }
|
2.序列求最大值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include<cstdio> #include<iostream> using namespace std; int a[1005],n; int find_max(int a[]) { int maxx=0; for(int i=0;i<n;i++) maxx=max(maxx,a[i]); return maxx; } int find_min(int a[]) { int minn=0x7fffffff; //七个f。这是十六进制表示,代表了int的上限 for(int i=0;i<n;i++) minn=min(minn,a[i]); return minn; } int main() { for(int i=0;i<n;i++)cin>>a[i]; cout<<find_max(a)<<" "<<find_min(a); return 0; }
|
3.不限行数输入
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include<cstdio> #include<iostream> using namespace std; char a[1005]; int main() { while(cin>>a) //或者写成scanf形式 //while(~scanf("%s",a)) { cout<<a; } return 0; }
|
4.一次读入一整行
使用getline函数读入char数组的方法上面已经说过了,这里补充强调一下,如果要把getline和cin一起使用的话,请加上清空输入缓冲区的函数
请看示例:
1 2 3 4 5 6 7 8 9 10 11 12
| #include<cstdio> #include<iostream> using namespace std; char a[1005]; int n; int main() { cin>>n; cin.getline(a,1000); cout<<n<<"\n"<<a; return 0; }
|
大家会发现这段代码里getline就和没写一样。原因是cin在读入n时只拿走了n的值,而没有拿走换行符,所以getline一读入换行符就结束了,和没有一样
这时候我们需要这样写
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include<cstdio> #include<iostream> using namespace std; char a[1005]; int n; int main() { cin>>n; cin.clear(); //清空输入流标识符,确保可以输入 cin.sync(); //清空输入流 cin.getline(a,1000); cout<<n<<"\n"<<a; return 0; }
|
这样就可以正常执行了