1. 程式人生 > 實用技巧 >字串-標準庫

字串-標準庫

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的取值兩臺電腦可能不一樣,但可以發現輸出的兩行是一樣的