C++ 文字の扱い No4

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

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

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

```c++
char moji = 'A';
char mojiretu[4] = "ABC";
```
1文字の時は''←この記号。複数の文字数の時は""←これ。（string型はこっちかな？）
この時メモリにはASCⅡコードに対応した数字（コード）が格納されている。[ASCⅡコード表](http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html)
'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.文字を文字列](http://www9.plala.or.jp/sgwr-t/c/sec02.html#s2-4)

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

```c++: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;
}
```
```c++:出力
97
a
b
```

##1-2.文字列を扱う関数
strcmp, strncmp…文字列の比較
strcpy, strncpy…文字列をコピー
strlen…文字列の長さ取得
strcat…文字列を連結

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

```c++: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++:出力
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引数に比べる文字の数_を指定する。

```c++: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;
}
```
```c++:出力
str1[]とstr2[]は一致
str1[]とstr3[]は一致しない
str1[]とstr4[]は一致しない
str1[]とstr4[]は一致
```


#参考文献
[2-4.文字を文字列](http://www9.plala.or.jp/sgwr-t/c/sec02.html#s2-4)
[ASCⅡコード表](http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html)
[【C言語入門】 文字・文字列(char)の使い方](https://www.sejuku.net/blog/25592)
[【C言語入門】文字列を比較する方法（strcmp、strncmp）](https://www.sejuku.net/blog/25303)
[std::outでポインタや変数のアドレスを表示する](http://kaworu.jpn.org/cpp/std::out%E3%81%A7%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%82%84%E5%A4%89%E6%95%B0%E3%81%AE%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)