文字の扱い方
文字列を扱う変数
これまで、プログラム中で何回も文字列を扱ってきたのですが、
なぜか、文字列を記憶する変数は1度も説明したことがありませんでした。
その理由は簡単です。C言語には
文字列を記憶する変数がないからです。
文字列用の変数がないのは、文字列が特殊な性質を持つためです。
文字列は、何文字になるのかが事前に予測できません。
5文字程度で済むこともあれば、何千文字という文字数になることもあります。
この様に、場合によって必要とされるメモリのサイズが異なってくるのです。
この様な事情があるため、C言語には文字列用の変数がありません。
C言語以外のプログラミング言語では、次のような構造で文字列変数を用意しています。
1、メモリを固定的に確保(メモリ消費量のムダが多くなるが、高速で扱いやすい)
2、メモリを可変的に確保(メモリ消費量を減らせるが、低速。)
このように、どちらも一長一短となっており、向き不向きがあります。
C言語では、プログラマーが自由な方法で文字列を表現できるようになっています。
文字を扱うには
前項では、C言語には、文字列変数はないと書きましたが、
文字列変数はなくても、
文字変数であれば用意されています。
文字列と違い、文字は必ず1文字であるため、変数で扱うことができるのです。
C言語では、文字変数として、
char(キャラ)型が用意されています。
char型の変数には、1文字を記憶しておくことができます。
文字は '' で囲むことで表現します。
また、%c指定子を使えば、printf関数で表示できます。
次のプログラムは、char型の変数に文字を記憶して表示する例です。
#include <stdio.h>
int main(void)
{
char c = 'A';
printf("%c\n", c);
return 0;
}
このプログラムの実行結果は、次の通りになります。
この様に、char型を使えば、文字を変数と同様に取り扱うことが可能です。
実は、この方法では、全角文字を扱うことはできません。
char型で記憶できる文字の種類は最大で255種類が限界で、
何千文字もある日本語の文字を記憶しておくことは出来ないのです。
この問題を解決する手段として、wchar_t型が用意されているのですが、
まずは基本の文字変数をしっかり覚えてほしいので、ここでは扱いません。
文字コード
前項では、char型で1文字を取り扱うことができることを説明しましたが、
これは、コンピュータで使われる
文字コードの仕組みを利用しています。
【文字コード】
コンピュータで使われる文字に1対1で対応する番号をつけて表現する方法。
ASCIIコードという規格では半角のアルファベットや記号が割り当てられている。
日本語を扱えるコードとして、JIS、シフトJIS、EUCが使われている他、
世界中の言語を扱えるコードとして Unicode が普及している。
文字コードとは、文字に1対1で対応する番号をつけて表現する方法のことです。
次の表は、半角文字の番号表としてもっとも使われている規格であるASCIIコードの例です。
番号 |
番号(16進数) |
文字 |
62 |
0x3e |
|
63 |
0x3f |
? |
64 |
0x40 |
@ |
65 |
0x41 |
A |
66 |
0x42 |
B |
67 |
0x43 |
C |
68 |
0x44 |
D |
97 |
0x61 |
a |
98 |
0x62 |
b |
こういった表を出すと、受験勉強のように丸暗記しようとする人が出てくるのですが、
暗記する必要はまったくありません。もちろん筆者も暗記しておりません。
実はAが65くらいは覚えていたりしますが・・・
重要なことは、文字には番号がついているという仕組みあり、番号そのものではありません
char型変数に文字を代入するのは、この番号を代入しているだけのことです。
つまり、実のところ、
char型は普通の整数型とまったく同じなのです。
たとえば、前項のプログラムでは、'A' をchar型変数cに代入しましたが、
これは、A が65番に割り当てられているので、コンパイラが 'A' を 65 と解釈し、
その65がcに代入されただけのことに過ぎません。
また、printf関数で A が表示されたのも、変数の中身が65だったので、
printf関数の方で A と表示するように処理しただけのことなのです。
つまり、コンピュータでは
すべての文字は番号で表されており、
char型はその番号を記憶しておくに過ぎないということなのです。
文字に対する計算
char型で記憶されている文字は、実は単なる番号であることを前項で説明しましたが、
このことを利用すれば、
文字に対して計算を行うこともできます。
たとえば、文字コードでは、基本的に文字の番号は順番通りに定義されています。
半角アルファベットでは、A が65、Bが66、Cが67、のように決められています。
つまり、Aに足し算を行うと、何番目のアルファベットの文字を取り出すことができます。
次のプログラムは、10番目のアルファベットを取り出す例です。
#include <stdio.h>
int main(void)
{
char c = 'A' + 9; /* 最初は0なので9を足す */
printf("%c¥n", c);
return 0;
}
このプログラムの実行結果は、次の通りになります。
数字を使う時には、引き算で本来の数値を知ることもできます。
数字にも文字の番号が割り当てられており、たとえば '0' は48番に割り当てられています。
数字から '0' の番号を引き算すれば、
数値に変換され計算に使用できます。
次のプログラムは、数字を数値に変換する例です。
#include <stdio.h>
int main(void)
{
char c = '8'; /* 数字 */
int suuti = c - '0'; /* 数値に変換 */
printf("%d\n",suuti);
return 0;
}
このプログラムの実行結果は、次の通りになります。
このプログラムでは、数値に変換した結果を%d指定子で表示させています。
ただし、先ほどのプログラムの問題点は、数字以外の文字も変換されることです。
たとえば、'A' は65番なので、'A' を数値に変換させると17になってしまいます。
この問題を解決するには、変換する文字が数字であるかを判定する必要があります。
これは比較的簡単です。文字の番号が、'0' ~ '9' の間にあるか調べるだけです。
次のプログラムは、数字を数値に変換し、数字以外はすべて0に変換する例です。
#include <stdio.h>
int main(void)
{
char c = 'A'; /* 数字 */
int suuti;
if (c >= '0' && c <= '9' ) {
/* 判定部分 */
suuti=c - '0' ; /* 数値に変換 */
} else {
suuti=0;
}
printf("%d\n",suuti); return 0;
}
このプログラムの実行結果は、次の通りになります。
もちろん、数字を指定した場合には、ちゃんと数値に変換されます。
ある文字が数値かどうかを調べる方法は、アルファベットにも応用できます。
ただし、大文字の 'Z' から小文字の 'a' には連続していないので、
'A' ~ 'Z' と 'a' ~ 'z' をそれぞれ調べる必要があります。
また、これらの機能は関数化されており、次の関数が使えます。
なお、これらの関数の使用には、ctype.h を #include する必要があります。
名前 |
文字種類 |
文字一覧 |
isalnum |
英数字 |
A~Z a~z 0~9 |
isdigit |
10進数 |
0~9 |
isxdigit |
16進数 |
A~F a~f 0~9 |
isalpha |
英字 |
A~Z a~z |
isupper |
英大文字 |
A~Z |
islower |
英小文字 |
a~z |
ispunct |
記号 |
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ |
isspace |
スペース |
0x09~0x0D 0x20 |
次のプログラムは、isdigit関数を使って先ほどのプログラムを書き換えた例です。
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char c = 'A';
int suuti;
if (isdigit(c)) {
/* 判定部分 */
suuti = c - '0';
} else {
suuti = 0;
}
printf("%d\n",suuti);
return 0;
}
実行結果は、先ほどまったく同じになります。