字串-標準庫
C++的寶庫
一 輸入輸出
請自動忽略
\(scanf\)
scanf("%s",s);
要注意的是字元陣列名\(s\)代表的是一個地址,所以不要加取地址符
如果要輸入一個\(char\)型別的字元,用\(scanf\)時,要注意空格和換行,\(scanf\)會把空格和換行也輸進去,要用\(getchar()\)吃掉一個字元。
那還是用cin吧
例:
輸入
HPPH
PHHP
HHPP
PHHH
for(int i=1;i<=4;++i){ getchar(); for(int j=1;j<=4;++j)scanf("%c",&a[i][j]); }
\(pritnf\)
printf("%s",s);
同上
(一定要看清楚題目要求輸出的字串有沒有空格,句點,換行!!!)
二 各種各樣奇怪的函式
\(strlen\)
大部分人都只知道這個吧
\(strlen(s)\)可以返回字串\(s\)的長度
例如,字串ABCDEFG的長度為7。
注意:\(strlen\)是從下標\(0\)開始的,使用時要想清楚字元陣列中儲存的字串下標從\(0\)還是\(1\)開始。
注意:只能用於字元陣列,用到\(string\)上會報錯
\(strcmp\)
要比較字串\(s1\)和\(s2\)是否一樣,怎麼辦呢?
if(s1==s2)printf("Yes.");
如果\(s1\)\(s2\)是由\(string\)定義的,那麼這樣是可以的。
但是用陣列定義的就不行了
所以我們就請出帶佬\(strcmp\)(但是\(strcmp\)也不能給\(string\)用啊)
int strcmp(const char *str1, const char *str2) :按照字典序比較 str1 str2 若 str1 字典序小返回負值,一樣返回 0,大返回正值 請注意,不要簡單的認為只有 0, 1, -1 三種,在不同平臺下的返回值都遵循正負,但並非都是 0, 1, -1
(來自OI Wiki)
實際是檢驗真理的唯一標準
#include<bits/stdc++.h> using namespace std; char s1[]="123456",s2[]="123456"; int main(){ printf("%d",strcmp(s1,s2)); } //輸出0
#include<bits/stdc++.h>
using namespace std;
char s1[]="12345",s2[]="123456";
int main(){
printf("%d",strcmp(s1,s2));
}
//輸出-1
#include<bits/stdc++.h>
using namespace std;
char s1[]="123456",s2[]="12345";
int main(){
printf("%d",strcmp(s1,s2));
}
//輸出1
注意:不要把\(strcmp\)塞給\(string\)用
\(strstr\)
奇怪的名字
char *strstr(char *str1, const char *str2) :若 str2 是 str1 的子串,則返回 str2 在 str1 的首次出現的地址;如果 str2 不是 str1 的子串,則返回 NULL 。
(來自OI Wiki)
實際是檢驗真理的唯一標準
#include<bits/stdc++.h>
using namespace std;
char s1[]="123456",s2[]="2345";
int main(){
printf("%d",strstr(s1,s2)-s1);
}
//輸出1
//相當於在s1中找到子串s2第一次出現的位置(地址)
//減去s1就變成了s1中子串s2第一次出現的下標
#include<bits/stdc++.h>
using namespace std;
char s1[]="123456",s2[]="789";
int main(){
printf("%d",strstr(s1,s2));
}
//輸出0
//在s1中找不到s2,返回NULL(變成0)
這個函式像開掛一樣
注意:是判斷\(s2\)是否\(s1\)的子串
注意:\(string\)太巨了,這個也不能用
\(strchr\)
\(strrchr\)
一對奇怪的函式
相類似於\(strstr\),但是看到\(str\)變成\(chr\)就知道這是用來尋找字元在字串中的位置的
char *strchr(const char *str, int c) :找到在字串 str 中第一次出現字元 c 的位置,並返回這個位置的地址。如果未找到該字元則返回 NULL 。
char *strrchr(const char *str, char c) :找到在字串 str 中最後一次出現字元 c 的位置,並返回這個位置的地址。如果未找到該字元則返回 NULL 。
(還是OI Wiki)
#include<bits/stdc++.h>
using namespace std;
char s1[]="123456123456",c='2';
int main(){
printf("%d %d",strchr(s1,c)-s1,strrchr(s1,c)-s1);
}
//輸出1 7
再次開掛
注意:\(string\)太巨了,這個還是不能用
三 \(string\)
巨佬
上述函式啥都不能用
那不虧爆?
?!
std::string
賦值運算子 = 右側可以是 const string/string/const char/char 。
訪問運算子 [cur] 返回 cur 位置的引用。
訪問函式 data()/c_str() 返回一個 const char* 指標,內容與該 string 相同。
容量函式 size() 返回字串字元個數。
還有一些其他的函式如 find() 找到並返回某字元位置。
std :: string 過載了比較邏輯運算子,複雜度是\(\Theta(N)\)的。
(還是來自OI Wiki)
輸入輸出
直接\(scanf\)或\(printf\)是會報錯的
直接\(cin\)和\(cout\)是可以的
以空格和換行為終止
#include<bits/stdc++.h>
using namespace std;
string s1;
int main(){
cin>>s1;
cout<<s1;
}
//輸入123 456
//輸出123
高階一點,請出\(getline()\)讀取一行
只以換行為終止,他會把空格也輸入進去
#include<bits/stdc++.h>
using namespace std;
string s1;
int main(){
getline(cin,s1);//奇怪的寫法
cout<<s1;
}
//輸入123 456
//輸出123 456
奇怪的運算
·可以用+來合併
#include<bits/stdc++.h>
using namespace std;
string s1="123",s2="456";
int main(){
cout<<s1+s2;
}
//輸出123456
·可以賦值
還可以用字元\(char\)來賦值
#include<bits/stdc++.h>
using namespace std;
string s1="123",s2="456";
int main(){
s1=s2;
cout<<s1;
}
//輸出456
#include<bits/stdc++.h>
using namespace std;
string s1="123";
char c='4';
int main(){
s1=c;
cout<<s1;
}
//輸出4
奇怪的函式
·\(s.empty()\)
判斷字串\(s\)是否為空(字元數為0)
#include<bits/stdc++.h>
using namespace std;
string s1="123";
int main(){
cout<<s1.empty();
}
//輸出0
#include<bits/stdc++.h>
using namespace std;
string s1;
int main(){
cout<<s1.empty();
}
//輸出1
·\(s.size()\)
返回字串字元個數
#include<bits/stdc++.h>
using namespace std;
string s1="123";
int main(){
cout<<s1.size();
}
//輸出3
·\(s1.find(s2)\)
找到並返回字串\(s2\)在\(s1\)中的位置(類似於下標)
#include<bits/stdc++.h>
using namespace std;
string s1="123456";
int main(){
cout<<s1.find("45");
}
//輸出3
如果沒找到,輸出\(s.npos\)
#include<bits/stdc++.h>
using namespace std;
string s1="123456";
int main(){
cout<<s1.find("78")<<endl;
cout<<s1.npos;
}
//npos的取值兩臺電腦可能不一樣,但可以發現輸出的兩行是一樣的