文字列

char 型

C 言語では、文字を取り扱う場合に、char 型を利用する。char 型の変数のサイズは 1 バイトと決められているので、1 つの変数には 1 文字しか保存できない。

#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 型の配列を利用する。この場合、配列のサイズは、変数を宣言するときに決める必要がある。char 型の配列に文字列を格納する場合、文字列の最後にヌル文字 \0 を入れる必要がある。次のようにダブルクオーテーションマークで変数を作成する場合は、自動的にヌル文字が文字列の終端に挿入されるが、シングルクオーテーションマークの場合は自動的に挿入されない。

#include <stdio.h>

int main(void) {
    char str1[] = "DNA";
    char str2[] = {'R', 'N', 'A', '\0'};

    printf("%s\n", str1);
    printf("%lu\n", sizeof(str1));
    // DNA
    // 4
    
    printf("%s\n", str2);
    printf("%lu\n", sizeof(str1));
    // RNA
    // 4

    return 0;
}

char 型ポインター

文字列を扱うには、char 型の配列を利用する他に、char 型のポインターを利用することもできる。

#include <stdio.h>

int main(void) {
    const char* char_ptr = "DNA";

    printf("%s\n", char_ptr);
    // DNA

    return 0;
}

string 型

C++ では string 型を利用すると、char 型の配列やポインターよりも、文字列の取り扱いが便利になる。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    std::string str1 = "DNA";
    std::string str2 = "RNA";
    std::string str3 = str1 + str2;
    
    std::cout << str3 << std::endl;
    // DNARNA

    return 0;
}

char 型から string 型への変換

char 型配列から string 型への変換

char 型配列から string 型に変換するとき、配列のサイズを指定する必要がある。次の例では、sizeof 関数を利用して、char 型配列のサイズを取得している。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    char arr[] = "CGTCAAACGG";

    std::string dna_seq(arr, sizeof(arr) / sizeof(arr[0]));

    std::cout << dna_seq << std::endl;
    // CGTCAAACGG

    return 0;
}

char 型ポインターから string 型への変換

char 型ポインターから string 型に変換するとき、string 型のコンストラクタを利用する。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    const char* char_ptr = "CGTCAAACGG";

    std::string dna_seq = std::string(char_ptr);

    std::cout << dna_seq << std::endl;
    // CGTCAAACGG

    return 0;
}

string 型の文字列操作

文字列へのアクセス

C++ の string 型の文字列中の文字にアクセスするには、変数に添字を代入すればいい。一文字目の添字は 0 から始まる。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    std::string seq = "CGTCAAACGG";

    std::cout << seq[0] << std::endl;
    // C
    std::cout << seq[1] << std::endl;
    // G

    return 0;
}

文字列の長さ

C++ の string 型の文字列の長さは、size() 関数を利用して調べることができる。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    std::string seq = "CGTCAAACGG";
    int seq_len = seq.size();

    std::cout << seq_len << std::endl;
    // 10

    return 0;
}

文字列の結合

複数の C++ の string 型の文字列を結合するには、+ 演算子を利用する。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    std::string exon_1 = "CGTCAAACGC";
    std::string exon_2 = "CGCCCGATAG";
    std::string exon_3 = "AACCAATTGT";
    std::string mRNA = exon_1 + exon_2 + exon_3;

    std::cout << mRNA << std::endl;
    // CGTCAAACGCCGCCCGATAGAACCAATTGT

    return 0;
}

文字列の検索

複数の C++ の string 型の文字列の中から特定の文字列を検索するとき、前から検索するときは find 関数、後ろから検索するときは rfind 関数を利用する。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    std::string seq = "CGTATACAAACCGGAGCGAAAAC";
    
    std::string::size_type trip_A_1 = seq.find("AAA");    
    if (trip_A_1 != std::string::npos) {
        std::cout << trip_A_1 << std::endl;
        // 7
    } else {
        std::cout << "AAA not found." << std::endl;
    }

    std::string::size_type trip_A_2 = seq.rfind("AAA");    
    if (trip_A_1 != std::string::npos) {
        std::cout << trip_A_2 << std::endl;
        // 19
    } else {
        std::cout << "AAA not found." << std::endl;
    }

    return 0;
}

文字列の置換

C++ の string 型の文字列の置換は replace 関数を利用する。

開始位置と終了位置を指定して置換する場合は、次のようにする。

#include <stdio.h>
#include <string>
#include <iostream>

int main(void) {
    std::string seq = "CGTCAACGTAACCTGC";
    
    seq.replace(0, 3, "AAAAAAAAAA");
    
    std::cout << seq << std::endl;
    // AAAAAAAAAACAACGTAACCTGC

    return 0;
}

特定の文字列だけを別の文字列に置換する。次の例は、文字列中のすべての T を U に置換している。

#include <stdio.h>
#include <string>
#include <iostream>

std::string replace_with_str (std::string str, std::string str_from, std::string str_to) {
    std::string::size_type pos = 0;
    while (pos = str.find(str_from, pos), pos != std::string::npos) {
        str.replace(pos, str_from.length(), str_to);
        pos += str_to.length();
    }
    return str;
}

int main(void) {
    std::string seq = "CGTCAACGTAACCTGC";
    std::string seq2 = replace_with_str(seq, "T", "U");
    
    std::cout << seq << std::endl;
    // CGTCAACGTAACCTGC
    std::cout << seq2 << std::endl;
    // CGUCAACGUAACCUGC

    return 0;
}