字符串基础处理相关(读入输出,函数)
由于我真的太菜了,可能有错。。。
中间涉及大量引用内容,并且内容及其基础
文中涉及到的一些摘抄的原文链接(原文可能更加精彩哦):
- https://blog.csdn.net/ysf13579/article/details/23447945
- https://blog.csdn.net/lanyzh0909/article/details/6957649
- https://blog.csdn.net/qq_33757398/article/details/81463542
- https://www.cnblogs.com/xzxl/p/7243490.html
- https://www.cnblogs.com/wkfvawl/p/9429128.html
- https://blog.csdn.net/cai_niaocainiao/article/details/81260902
- https://www.cnblogs.com/163467wyj/p/10072656.html
- https://www.cnblogs.com/meihao1203/p/9670680.html
文章目录
读入输出
cin,cout:
string s;
cin>>s;
cout<<s<<endl;
char s1[100];//和上面那个效果相同,但我以前也没用过
cin>>s1;
cout<<s1;
这这这,我以前也不知道cin,cout竟然就能这么读入输出字符数组
cin读入字符串时遇到空格或换行符就会结束
Example Input:
aa bb
Example output:
aa
cin.getline:
摘自https://blog.csdn.net/ysf13579/article/details/23447945
此函数一次读取多个字符(包括空白字符),直到读满N-1个,或者遇到指定的结束符为止(默认的是以’\n’结束)。其语法为:cin.getline(字符指针(char),字符个数N(int),结束符(char));*
#include<iostream>
using namespace std;
int main()
{
char a[10];
cin.getline(a,10);
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
return 0;
}
输入:1234567890123
输出:1 2 3 4 5 6 7 8 9 _ (第10位存放字符串结束符’\0’)
注意:cin.getline()函数缺省的第三个参数为’\n’,如果把cin.getline(a,10)改为cin.getline(a,10,’#’)
#include<iostream>
using namespace std;
int main()
{
char a[10];
cin.getline(a,10,'#');
cout<<a<<endl;
return 0;
}
输入:1234#567890
输出:1234
getline:
摘自https://blog.csdn.net/ysf13579/article/details/23447945
注意:与cin.getline功能类似,但是参数不一样,也属于两个不同的流,是两个不一样的函数。getline接受的字符串长度不受限制
#include<string>//getline包含在string头文件里
#include<iostream>
using namespace std;
int main()
{
string str;
getline(cin,str,'#');
char c=getchar();
cout<<str<<' '<<c<<endl;
return 0;
}
输入为:aa#b
输出为:aa b
//以上三个支持字符串,以下似乎就只支持字符数组??
gets:
摘自https://blog.csdn.net/ysf13579/article/details/23447945
C中的函数。可以无限读取,不会判断上限,以回车结束读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出
与getline函数功能相似,但是不能自定义结束符,只能换行符结束
#include "stdio.h" //这个头文件包含gets()函数
int main(void)
{
char str1[5];
gets(str1);
printf("%s\n", str1);
return 0;
}
输入:ab c
输出:ab c
puts
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s[1010]={"hello world"};
puts(s);
puts("dsa");
}
Example Output:
hello world
dsa
这你发现人家如此优秀,自动换行,貌似也只支持字符数组
scanf,printf
这个似乎大家都很熟悉,但好像也就支持字符数组,scanf读入字符数组忽略空格换行符什么的
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s[1000];
scanf("%s",s);
printf("%s",s);
}
Example Input:
aa bb
Example Output:
aa
下标从1开始
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s[1000];
scanf("%s",s+1);
printf("%c %c\n",s[0],s[1]);
printf("%s",s+1);
}
Example Input:
aa
Example Output:
? a
aa
这好像s[0]乱码了…
getchar()
读单个字符的
人家跑的很快,特别猛,但它什么都读…
char ch;
ch=getchar();
效率:
scanf,printf是要比cin,cout快的
gets要比getline快,貌似getline比cin.getline()快??
puts()速度不太清楚,好像挺快的
getchar()很快的
整形和字符串混合读入
如果用cin的话就没什么问题
scanf读入字符的话,是会把空格读入的,所以你得让它读入字符串也就是字符数组(参数不同,一个是%c,一个是%s),判断的话可以判首字母,直接用一个字符数组和一个字符串比较貌似也会出错。
或者也可以用getchar()一个一个读入,判断是否是字母
字符数组相关
strlen()
这个是测长度的,效果真的和size()差不多…
如果读入下标从1开始那么就是
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s[1000];
scanf("%s",s+1);
int l=strlen(s+1);
printf("%d",l);
}
Example Input:
aa
Example Output:
2
strcpy()
这个是赋值的,
strcpy(s1,s2)
但是
它貌似不能将一个字符串变量赋值给字符串数组
它可以赋值一个字符串常量给字符数组(strcpy(s,“hello”);),或者将一个字符数组赋值给另一个字符数组(strcpy(s1,s2);)
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s1[110],s2[110];
scanf("%s",s2);
strcpy(s1,s2);
printf("%s",s1);
}
Example Input:
dsadas
Example Output:
dsadas
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s1[110],s2[110];
strcpy(s1,"hello");
printf("%s",s1);
}
Example Output:
hello
字符串变量赋值给字符数组
由于不知道快速输出字符串的方法,我就想把它转为字符数组输出(似乎没有什么必要)
但是我至今没能找到将字符串赋值给字符数组的快速方法
以下方法貌似可以
#include <bits/stdc++.h>
using namespace std;
int main()
{
string S;
char s[110]={};//这里一定要有初始化
cin>>S;
for (int i=0;i<S.size();i++)
s[i]=S[i];
printf("%s",s);
}
Example Input:
aadsad
Example Output:
aadsad
字符串相关
首先字符数组是可以直接赋值给它的
然后据说有种名为string类的东西(我觉得就是平常写得完整版),
https://blog.csdn.net/lanyzh0909/article/details/6957649
这个就可以参考参考啦,最后也有很多函数
下面是比较常用的一些函数(事实上我觉得字符串操作并不怎么常用啊,但要是考,那就比较尬是吧
注意字符串的下标是从0开始的
迭代器
摘自:https://blog.csdn.net/qq_33757398/article/details/81463542
定义/格式:
string::iterator it;
这样就定义了一个string类型的迭代器ite,迭代器就相当于一个指针,一个string类型的迭代器就是一个指向string对象元素的char *指针,本质就是char *指针,用法也跟指针一样
具体参考blog
size()
这个就很常用了,得到字符串的长度
substr()
摘自:https://www.cnblogs.com/xzxl/p/7243490.html
#include<string>
#include<iostream>
using namespacestd;
int nmain()
{
string s("12345asdf");
string a = s.substr(0,5); //获得字符串s中从第0位开始的长度为5的字符串
cout << a << endl;
}
输出结果为:12345
用途:
一种构造string的方法
形式:
s.substr(pos, n)
解释:
返回一个string,包含s中从pos开始的n个字符的拷贝(pos的默认值是0,n的默认值是s.size() - pos,即不加参数会默认拷贝整个s)
补充:
若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾
find()
这复杂度O(m*n),如果你会kmp,那可能就不怎么用它了
第1个用的比较多吧
摘自:https://www.cnblogs.com/wkfvawl/p/9429128.html 作者:落墨幽微
1.string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos。(返回值可以看成是一个int型的数)
1 #include<cstring>
2 #include<cstdio>
3 #include<iostream>
4 using namespace std;
5 int main()
6 {
7 ////find函数返回类型 size_type
8 string s("1a2b3c4d5e6f7jkg8h9i1a2b3c4d5e6f7g8ha9i");
9 string flag;
10 string::size_type position;
11 //find 函数 返回jk 在s 中的下标位置
12 position = s.find("jk");
13 if (position != s.npos) //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,
14 {
15 printf("position is : %d\n" ,position);
16 }
17 else
18 {
19 printf("Not found the flag\n");
20 }
21 }
2.返回子串出现在母串中的首次出现的位置,和最后一次出现的位置。
1 flag = "c";
2 position = s.find_first_of(flag);
3 printf("s.find_first_of(flag) is :%d\n",position);
4 position = s.find_last_of(flag);
5 printf("s.find_last_of(flag) is :%d\n",position);
3.查找某一给定位置后的子串的位置
1 //从字符串s 下标5开始,查找字符串b ,返回b 在s 中的下标
2 position=s.find("b",5);
3 cout<<"s.find(b,5) is : "<<position<<endl;
4.查找所有子串在母串中出现的位置
//查找s 中flag 出现的所有位置。
flag="a";
position=0;
int i=1;
while((position=s.find(flag,position))!=string::npos)
{
cout<<"position "<<i<<" : "<<position<<endl;
position++;
i++;
}
5.反向查找子串在母串中出现的位置,通常我们可以这样来使用,当正向查找与反向查找得到的位置不相同说明子串不唯一。
1 //反向查找,flag 在s 中最后出现的位置
2 flag="3";
3 position=s.rfind (flag);
4 printf("s.rfind (flag) :%d\n",position);
replace()
摘自https://blog.csdn.net/cai_niaocainiao/article/details/81260902
详细请看blog,blog里有9种用法并附上代码
线性时间内执行———其复杂度为O(n)。
用法一:
用str替换指定字符串从起始位置pos开始长度为len的字符
string& replace (size_t pos, size_t len, const string& str);
用法二:
用str替换 迭代器起始位置 和 结束位置 的字符
string& replace (const_iterator i1, const_iterator i2, const string& str);
其它的感觉都差不多,有兴趣请看blog
erase()
摘自(然后篡改…瞎写一个代码):https://www.cnblogs.com/163467wyj/p/10072656.html
(1)erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
(2)erase(position);删除position处的一个字符(position是个string类型的迭代器)
(3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器)
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s1="Hello World";
string s2="Hello World";
string s3="Hello World";
s1.erase(1,2);
cout<<s1<<endl;
string::iterator iit=s2.begin()+2;
s2.erase(iit);
cout<<s2<<endl;
string::iterator it=s3.begin()+1;
string::iterator itt=s3.begin()+5;
s3.erase(it,itt);//貌似不包括itt指的那个字符
cout<<s3;
}
Example Output:
Hlo World
Helo World
H World
insert()
https://www.cnblogs.com/meihao1203/p/9670680.html
这篇博客写得很详尽,在此不再赘述
compare()
这个用的不多,也不是很有用的样子。
这里主要是说明字符串大小的比较是按字典序大小比较的
s1.compare(s2)
如果相等则返回0,不相等则返回1