Help us understand the problem. What is going on with this article?

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

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

文字列の削除

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)); 

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away