C++ 文字の扱い No4


概要

アホほど文字列の操作がダメだったので、これは基本的なとこから纏めるしかないと。char型。string型は機会があったら纏めたいな。

目次

1.char
1-1.charの基本
1-2.文字列を扱う関数
1-3.文字列の比較 strcmp

1.char

1-1.charの基本

char型は1バイトであり。文字が1文字かそれ以上で格納方法が変わる。

char moji = 'A';
char mojiretu[4] = "ABC";

1文字の時は''←この記号。複数の文字数の時は""←これ。(string型はこっちかな?)
この時メモリにはASCⅡコードに対応した数字(コード)が格納されている。ASCⅡコード表
'A'なら65が格納されている。そして複数の文字の場合には1番最後に'0'が付くため、3文字でも配列を4つ宣言している。
→文字列を使いたいときは 文字の長さ+1 の配列が必要。

初期化する場合にも終了コードを付けなければならない。この終了コードは文字列の終了、最後を表しNUL(ナル)と呼ぶ。

char str[10] = {'H','E','L','L','O','\0'};
//'\0'(コード:0)をつける

char str[10] = "HELLO";
//'\0'(コード:0)はコンパイラが自動的につける

初期化の際に出るエラー等のパターンはこちら2-4.文字を文字列

文字をint型の変数に入れると、文字コードが表示される。またchar型でも内部では文字コードで扱っているので、for文とかも回せちゃう。

sample1
#include <bits/stdc++.h>
using namespace std;
//cin.sync_with_stdio(false);

#define FOR(i,a,b) for(int i = (a); i < (b); ++i)
#define rep(i,n) FOR(i,0,n)

int main(int argc, char const *argv[])
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    char moji1, moji2;

    moji1 = 'a';
    moji2 = 'c';

    int c = 'a';
    cout << c << endl;

    for (char c = moji1; c < moji2; ++c)
    {
        cout << c << endl;
    }

    return 0;
}
出力
97
a
b

1-2.文字列を扱う関数

strcmp, strncmp…文字列の比較
strcpy, strncpy…文字列をコピー
strlen…文字列の長さ取得
strcat…文字列を連結

1-3.文字列の比較 strcmp, strncmp

数値のように「==」を用いて比較するとアドレスが同じか否かの比較になる。しかし、1文字の比較をする場合は文字コードという整数値を使って文字を比較することができる。
1文字分の文字が格納された変数との比較もできる。

sample2
#include <bits/stdc++.h>
using namespace std;
//cin.sync_with_stdio(false);

#define FOR(i,a,b) for(int i = (a); i < (b); ++i)
#define rep(i,n) FOR(i,0,n)

int main(int argc, char const *argv[])
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    char str[] = "Hello World!";

    char s = 'e';
    int c = 'e';
    char *p;
    p = str;

    cout << "cの文字コードは" << c << endl;
    cout << "str[1] eの文字は" << str[1] << endl;

    if (str[1] == 'e')
    {
        cout << "str[1]とeは一致" << endl;
    }else{
        cout << "str[1]とeは一致しない" << endl;
    }

    if (str[1] == s)
    {
        cout << "str[1]とs(e)は一致" << endl;
    }else{
        cout << "str[1]とs(e)は一致しない" << endl;
    }
    cout << endl;
    //アドレスを参照したかったが、なんか凄いことになった
    cout << p + 1 << endl;
    cout << &str[1] << endl;
    cout << &s << endl;

    return 0;
}
出力
cの文字コードは101
str[1] eの文字はe
str[1]eは一致
str[1]s(e)は一致

ello World!
ello World!
eHello World!

strcmp関数では第1、第2引数に比較したい文字列のchar型オブジェクトのポインタの定数値をとる。
要は引数にポインタを渡さなきゃならん

文字列は文字の配列になっているため、先頭から文字コードを使って比較していく。

・第1引数 < 第2引数 の場合はマイナスの値
・第1引数 > 第2引数 の場合はプラスの値
・第1引数 = 第2引数 の場合は0

を返します。

大文字の方が小文字の方が文字コードが小さいため、それを用いて大文字か小文字かの区別できる。

strncmpでは_第3引数に比べる文字の数を指定する。

sample3
#include <bits/stdc++.h>
using namespace std;
//cin.sync_with_stdio(false);

#define FOR(i,a,b) for(int i = (a); i < (b); ++i)
#define rep(i,n) FOR(i,0,n)

int main(int argc, char const *argv[])
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    char str1[20] = "Hello World!";
    char str2[] = "Hello World!";
    char str3[] = "hello world!";
    char str4[] = "Hello";

    /*
    char *str1 = "Hello World!";
    これもあり
    */

    //配列名はその配列の先頭アドレスを表すので可
    if (strcmp(str1, str2) == 0)
    {
        cout << "str1[]とstr2[]は一致" << endl;
    }else{
        cout << "str1[]とstr2[]は一致しない" << endl;
    }

    if (strcmp(str1, str3) == 0)
    {
        cout << "str1[]とstr2[]は一致" << endl;
    }else{
        cout << "str1[]とstr3[]は一致しない" << endl;
    }

    if (strcmp(str1, str4) == 0)
    {
        cout << "str1[]とstr4[]は一致" << endl;
    }else{
        cout << "str1[]とstr4[]は一致しない" << endl;
    }

    if (strncmp(str1, str4, 5) == 0)
    {
        cout << "str1[]とstr4[]は一致" << endl;
    }else{
        cout << "str1[]とstr4[]は一致しない" << endl;
    }

    return 0;
}
出力
str1[]str2[]は一致
str1[]str3[]は一致しない
str1[]str4[]は一致しない
str1[]str4[]は一致

参考文献

2-4.文字を文字列
ASCⅡコード表
【C言語入門】 文字・文字列(char)の使い方
【C言語入門】文字列を比較する方法(strcmp、strncmp)
std::outでポインタや変数のアドレスを表示する