427
351

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++ の文字列操作まとめ

Last updated at Posted at 2019-03-10

AtCoderに取り組んでいて迷うことが多々あったので、
C++における文字列の操作についてまとめます。(適宜追記予定です)

##基本
文字列変数の宣言・値の代入を行い、標準出力します。

sample.cpp
#include<iostream>
#include<string>
using namespace std;

int main() {
  string s1 = "testtest";
  string s2 = "";
  string s3 = "TEST";
  
  cout << "s1=" << s1 << ", s2=" << s2 << ", s3=" << s3 << endl; 
}
result
s1=testtest, s2=, s3=TEST

##n番目文字の抽出
[ ]で取得したい文字列のインデックスを指定します。

extract
  s1 = "testtest";
  char c = s1[3];
  cout << "c = " << c << endl;
result
c = t

##文字列の長さを取得
size()を使用します。

length
  s1 = "testtest";
  s2 = "";
  cout << "s1.size()= " << s1.size() << endl;
  cout << "s2.size()= " << s2.size() << endl;
result
s1.size()= 8
s2.size()= 0

##文字列が空かどうか判定
empty()を使用します。

checkIfEmpty
  S1 = "testtest";
  s2 = "";
  cout << "s1.empty = " << s1.empty() << endl;
  cout << "s2.empty = " << s2.empty() << endl;
result
s1.empty = 0
s2.empty = 1

s2は空の文字列なので1 (=true)が返ってきます。

##文字列の連結
シンプルに + で足し算できます

sum
  string s1 = "testtest";
  string s3 = "TEST";

  string s1pls3 = s1 + s3;
  cout << "s1 + s3 = " << s1pls3 << endl;
result
s1 + s3 = testtestTEST

##文字列の分割
n番目以降の文字列を取り出す場合はsubstr(n)とします。

sub1
  s1 = "testtest";
  cout << "s1.substr(3) = " << s1.substr(3) << endl;
result
s1.substr(3) = ttest

n番目以降の文字列をm文字だけ取り出す場合はsubstr(n, m)とします。

sub2
  s1 = "testtest";
  cout << "s1.substr(3,3) = " << s1.substr(3,3) << endl;
result
s1.substr(3,3) = tte

##文字列を任意の文字で分割
任意の文字での文字列分割(split)はc++に定義されていません。
自分で実装しましょう!
参考: C++におけるstringのsplit

##文字列の削除
n文字目以降の文字列を削除したい場合はerase(n)とします。

erase1
  s1 = "testtest";
  cout << "s1.erase(3) = " << s1.erase(3) << endl;
result
s1.erase(3) = tes

n文字目以降の文字列をm文字だけ削除したい場合はerase(n, m)とします。

erase2
  s1 = "testtest";
  cout << "s1.erase(3,2) = " << s1.erase(3, 2) << endl;
result
s1.erase(3,2) = tesest

##文字列の挿入
n文字目から文字列Xを挿入したい場合はinsert(n,X)とします。

insert
  s1 = "testtest";
  cout << "s1.insert(3,IN) = " << s1.insert(3, "IN") << endl;
result
s1.insert(3,IN) = tesINttest

##文字列の検索
探索したい文字列Xを用いてfind(X)とすると、該当する位置を返します。

find1
  s1 = "testtest";
  cout << "s1.find(s) = " << s1.find("s") << endl;
result
s1.find(s) = 2

sの最初の出現位置が返ります。

もしも検索文字列が見つからない場合には以下のようになります。

find1
  s1 = "testtest";
  cout << "s1.find(w) = " << s1.find("w") << endl;
result
s1.find(w) = 18446744073709551615

検索文字列が見つからないときは string::npos という値が返るようです。
それが何故こんな大きな数字になるのかは、以下の記事で解説されています。
std::string::nposの正体

では string::nposを使って、検索失敗の場合の場合分けをしてみます。

find3
  s1 = "testtest";
  cout << "s1.find(W) == string::npos --> " << (s1.find("W") == string::npos) << endl;
result
s1.find(W) == string::npos --> 1

"testtest" の中に "W"は含まれないので、string::nposとなっています(1 (=true)が返ります)。

##文字列の置換
n番目から数えてm個の文字列をXに置換したい場合はreplace(n,m,X)とします。

find3
 s1 = "testtest";
 cout << "s1.replace(2, 1, W) = " << s1.replace(2, 1, "W") << endl;
result
s1.replace(2, 1, W) = teWttest

##文字列の比較(一致判別)
文字列と文字を用いた比較の例です。

comp
//文字列
if(s1 == "test" ){
 cout << "test" << endl;
}
//文字
if(s1[0] == 't' ){
 cout << "t" << endl;
}

##文字列の比較2(小文字大文字英数字判別)

英字大文字小文字数字の判定。(ひらがなカタカナ漢字の判別は、またどこかで必要になったら調べて追記します)

comp
//文字が英小文字かどうか判定
if(s1[0] >= 'a' && s1[0] <= 'z'){
 cout << "small" << endl;

//文字が英大文字かどうか判定
}else if(s1[0] >= 'A' && s1[0] <= 'Z'){
 cout << "large" << endl;

//文字が数字かどうか判定
}else if(s1[0] >= '0'){
 cout << "number" << endl;
}

もしくは #includeとして、isalpha(判別したい文字)や isdigit(判別したい文字)を利用できます。

example
#include<iostream>
#include <ctype.h>
using namespace std;

int main() {
  char s;

  cout << "input: " ;
  cin >> s;

  cout << "isalpha: "<<  isalpha(s) << endl;//アルファベットかどうか
  cout << "isdigit: "<<  isdigit(s) << endl;//数字かどうか
  cout << "islower: "<<  islower(s) << endl;//小文字かどうか
  cout << "isupper: "<<  isupper(s) << endl;//大文字かどうか
}  
result
//アルファベット&小文字入力
input: a
isalpha: 1024
isdigit: 0
islower: 512
isupper: 0

//数字入力
input: 1
isalpha: 0
isdigit: 1
islower: 0
isupper: 0

//アルファベット&大文字入力
input: A
isalpha: 1024
isdigit: 0
islower: 0
isupper: 256

##文字列から数字型へ変換

sstream を使用して、string型に入った数字文字列をint型に変換します。

str2int
#include<iostream>
#include<string>
#include <sstream>
using namespace std;

int main() {
 string s1;
 istringstream ss1;
 int p1;

 cin >> s1;
 ss1 = istringstream(s1);
 ss1 >> p1;

//数字が入ったp1を操作

}

##文字型から数字型へ変換
一文字ずつなら難しいことしなくても数字型にできます。

char2int
  string s = "1";
  int a = s[0]-'0';
  a += 5;

  cout <<  a << endl;
resilt
6

##文字列の並び替え
sortを使用して降順昇順並び替えを行います。
(英数字以外には使えないかな...)

sort
 s1 = "482tTest";

 sort(s1.begin(), s1.end());
 cout << s1 << endl;

 sort(s1.begin(), s1.end(), greater<char>());
 cout << s1 << endl;
result
248Testt  //数字1-9▶英大文字A-Z▶英小文字a-z
ttseT842  //英小文字z-a▶英大文字Z-A▶数字9-1

##英文字をアルファベット順でN個後にずらして出力 
参考: abc146 B
こんな感じ?

string s1 = "test";
int N = 5;
printf("%c", (s1[0]+N)); 

##末尾の文字削除/末尾に文字追加
参考: abc043 B
pop, pushが使える

string s1 = "test";

//末尾に'2'を追加
s1.push_back('2');

//末尾の文字削除
s1.pop_back();

##回文判定
reverseで反転を行い、元文字列と比較することで実現できます。
(後日 追記)


以上です。
また何かあれば追記していきます。

427
351
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
427
351

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?