2.12.5. 文字列#
2.12.5.1. char 型#
C/C++ 言語では、1 文字を扱うために char 型を使用します。char 型のサイズは 1 バイトと決められており、1 つの変数には 1 文字しか格納できません。次の例では、3 つの char 変数にそれぞれ文字を代入し、まとめて出力しています。
#include <stdio.h>
int main(void) {
char a = 'D';
char b = 'N';
char c = 'A';
printf("%c%c%c\n", a, b, c); // DNA
return 0;
}
複数の文字からなる文字列を扱う場合は、char 型の配列を利用します。このとき、文字列の最後には必ずヌル文字 \0 を置く必要があります。ダブルクォーテーションで文字列を指定した場合は、ヌル文字が自動的に追加されます。
#include <stdio.h>
int main(void) {
char str1[] = {'R', 'N', 'A', '\0'};
printf("%s (%lu)\n", str1, sizeof(str1)); // RNA (4)
char str2[] = "DNA";
printf("%s (%lu)\n", str2, sizeof(str2)); // DNA (4)
return 0;
}
2.12.5.2. char 型ポインター#
文字列は、char 型の配列だけでなく、char 型ポインターでも扱うことができます。文字列リテラルを指すポインターを使う場合、内容を書き換えないため const char* とするのが一般的です。
#include <stdio.h>
int main(void) {
const char* str = "DNA";
printf("%s\n", str); // DNA
return 0;
}
2.12.5.3. string 型#
C++ では std::string 型を使うことで、文字列をより安全かつ簡単に扱えます。文字列の結合や長さの取得などが直感的に行える点が特徴です。
#include <iostream>
#include <string>
int main() {
std::string str1 = "DNA";
std::string str2 = "RNA";
std::cout << str1 + str2 << std::endl; // DNARNA
return 0;
}
char 型配列は、そのまま std::string に渡すことで変換できます。配列の場合はヌル文字までが自動的に文字列として扱われます。
#include <iostream>
#include <string>
int main() {
char arr[] = "CGTCAAACGG";
std::string dna_seq(arr);
std::cout << dna_seq << std::endl; // CGTCAAACGG
return 0;
}
char 型ポインターから変換する場合も同様に変換できます。
#include <iostream>
#include <string>
int main() {
const char* ptr = "CGTCAAACGG";
std::string dna_seq(ptr);
std::cout << dna_seq << std::endl;
return 0;
}
std::string では、文字列を配列と同じように扱うことができます。例えば、インデックスを指定して特定の文字にアクセスできます。
#include <iostream>
#include <string>
int main() {
std::string seq = "CGTCAAACGG";
std::cout << seq[0] << " " << seq[1] << std::endl; // C G
return 0;
}
文字列の長さは size() で取得できます。
#include <iostream>
#include <string>
int main() {
std::string seq = "CGTCAAACGG";
std::cout << seq.size() << std::endl; // 10
return 0;
}
複数の文字列を連結する場合は、+ 演算子を使います。
#include <iostream>
#include <string>
int main() {
std::string mRNA = "CGTCAAACGC" + std::string("CGCCCGATAG") + "AACCAATTGT";
std::cout << mRNA << std::endl;
return 0;
}
文字列中から特定の部分文字列を探すには、find または rfind を使用します。find は前から、rfind は後ろから検索します。見つからない場合は std::string::npos が返されます。
#include <iostream>
#include <string>
int main() {
std::string seq = "CGTATACAAACCGGAGCGAAAAC";
auto pos1 = seq.find("AAA");
auto pos2 = seq.rfind("AAA");
std::cout << pos1 << std::endl; // 7
std::cout << pos2 << std::endl; // 19
return 0;
}
replace を使うと、指定した位置と長さの文字列を別の文字列に置き換えられます。
#include <iostream>
#include <string>
int main() {
std::string seq = "CGTCAACGTAACCTGC";
seq.replace(0, 3, "AAAAAAAAAA");
std::cout << seq << std::endl;
return 0;
}
特定の文字をすべて別の文字に置き換えたい場合は、find と replace を組み合わせて処理します。次の例では、すべての T を U に置き換えています。
#include <iostream>
#include <string>
int main() {
std::string seq = "CGTCAACGTAACCTGC";
for (auto pos = seq.find('T'); pos != std::string::npos; pos = seq.find('T', pos + 1)) {
seq.replace(pos, 1, "U");
}
std::cout << seq << std::endl; // CGUCAACGUAACCUGC
return 0;
}