字符串讲义
1、单个字符用‘’,字符串可以用”“,输出空格时可以用cout << ” “;
2、字符串的存储。定义在函数内部的字符串变量一般会在计算机当中连续存储,例如:
char a[]={'C','+','+'};
char b[]={'B','+','+','/0'};
cout << a;
上述代码输出时,会输出“CB”,是因为a,b两数组存储在计算机中可能是连续存储的,即“C + + B + + /0”,故当输出a[]时,会一直输出到‘/0’才结束。这种情况与计算及自身存储有关,很随机,可以在两字符串数组间定义一些其他变量以隔离他们在计算机中的存储位置。
3、C++中’/0’表示0 ;
4、输入输出:
(1)数组b从中间部分输出(输入)的巧妙用法
char b[]={'A','B','C','\0'};
cout << b <<endl;
cout << b+1 << endl;
则输出为:
ABC
BC
char s[10];
cin >> s+1; // 即从s[1]开始存
(2)字符数组输入(三种方法,scanf、cin、for循环赋值)
char a[100];
scanf("%s",a); //注意这里直接读入字符串,不用取地址符号&
cin >> a;
for(int i=0;i<100;i++){
scanf("%c",&a[i]);
}
scanf(“%s”,a); 因a[]本身就有指示位置的指针,&也起到指针的作用,再加取地址符号&就会出错。
注意:scanf输入整个数组只能以下读入一整个字符串数组,整形数组还得用循环一个一个输入。string只能用cin读入,不能用scanf
(3)cin遇到空格、回车会停止,cout只有遇到’\0’才会停止。故输出一整行带有空格的字符串时,可用getline(),fgets()。
fgets(s,100,stdin) :可以读到一个字符串中
s为输入的字符串,100为输入端限长,stdin为系统内部提供的(固定),是把输入的字符串当文件来读入;
注意字符数组输入时,fgets()会把回车(换行/新行’\n’)计算在字符串长度中,scanf也不会过滤回车(7、中有记录)。而用string可以自动过滤回车。
因此当用fgets()读入字符数组,输出时puts()会输出回车,可以用printf()输出,他可以过滤回车。
char str[100];
for(int i=0;i<30;i++)
cin >> str[i];
printf("%s",str); // 可以直接输出字符数组中的所有字符
getline(cin,s) :只能读到一个string变量中。
如果字符数组也想用getline输入,则用cin.getline(s,100);
(4)输出:puts(s) 与 printf(“%s\n”,s)等价,即puts()会自己补上换行符
5、计算字符数组长度可以用strlen(),它只计字符个数不包括’/0’;
计算字符串长度可以用s.size()或s.length(),也不计’/0’
注意:当遍历数组用for(int i=0;i<s.strlen();i++),效率不高,相当于s.strlen()进行了n次(n=s.strlen() )
因为它相当于一个双重循环,strlen()实现时也是有一个循环。可以先用一个变量x存一下字符数组长度,这样遍历数组时就不用每次比较i大小时都再循环计算s的长度(相当于)
但是s.size()的时间复杂度为O(1),它不需要循环,只是存了字符串的长度,它是很快的,与s.strlen()不同。(s.strlen()时间复杂度为O(n))
6、若字符数组或字符串或随便什么变量长度比较大,最好定义为全局变量
7、C++中用scanf输入时需注意它不会过滤回车,例如:
char s[10];
scanf("%s",s);
char c;
scanf("%c",&c); //可以用scanf("\n%c",&c) 过滤回车
cout << s << endl << c;
/*
样例输入:
hello
l
输出:
hello
*/
8、string
(1)string不能用scanf输入,但可以用printf输出:
printf(“%s\n”,s.c_str()) 与 cout << s << endl 效果相同;
当然输出可以用puts()。
(2)字符串可以累加(字符串只能做加法,不能做乘法、除法)
string s1,s2,s;
s=s1+s2;
s=s+" is great"+'!'; // 假如s1="abc",s2="uhk",则s="abcuhk is great!"
//不可以是 s += " is great"+'!'; 但 s+='!'可以。
//因为当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string
且加法左右两边只要有一个是string类型,那么另外一边也会自动转化为string类型
(3)基于范围的for语句:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "hello world";
for (char c: s) cout << c << endl;
// for(auto c:s) : auto“自动类型推导” 编译器自己“猜” c 是什么类型,可能会猜错
for (char& c: s) c = 'a';
cout << s << endl;
return 0;
}
(4)pop_back()删除字符串最后一个字符;
a.substr(x,len) //返回从字符串下标为x的字符开始,长度为len的串(a.substr(x) 就是从x一直输出到字符串结尾)