文字をコンピューターのメモリーに格納させるためには,その文字が持つ情報量を考えな
くてはならない.先に述べたように,1文字記憶するためには英数字では1バイト,日本語
では2バイトが必要である.これは,記憶させるための箱(変数)の大きさが,日本語では
英語の2倍必要と言うことである.
通常の文字の処理では,1文字では余り役に立たない.普通の文章は,文字が連なって,
一つの情報の固まりとなっている.このように文字が連なったものを文字列と言う.
この様な場合,文字型の配列を使うことになる.このようなことから,文字の状態によっ
て,記憶方法を変える必要がある.これは,プログラマーに対して,厳しいことを要求し
ている.ちゃんと理解するためには,少しだけハードウェアーの知識が必要になる.
ここでは,このような文字をメモリーへ格納する方法を示す.
英数字1文字の場合,これは単純で文字型変数を用いる.次のように宣言をすれば,変数
名
hogeの文字を入れる入れ物が用意される.この入れ物の容量は,1バイトである.
char hoge;
型名の
charと言うのは,character(文字)の略である.このように宣言した文字型の
変数には,ひとつの英数字が格納できる.これまで学習してきた数値と同様に,代入演算
子(
=)を使う.具体的には,次のようにする.
hoge = 'A';
格納したい文字をシングルクォーテーションで囲むことを忘れてはならない.シングル
クォーテーションで囲まれたひとつの英数字--ここでは
A--が文字型の変数に格納
される.
文字型変数のイメージを,図1に示す.
図 1:
文字型変数hogeを用意して,それに'A'を格納.この箱の大きさは,1バ
イトなので,日本語を入れることはできない.
|
表示まで含めた文字型変数を使ったプログラムは,次のようになる.文字型変数を表示さ
せるためには,変換指定子%cを用いる.cは,characterの略であろう.
#include <stdio.h>
int main(void){
char hoge; /* 文字型の変数 */
hoge='A'; /* 代入 */
printf("%c\n",hoge); /* 表示 */
return 0;
}
次に,いくつかの英数字で構成される文字列の場合である.このようなときは,文字型の
配列のデータ構造を使う.以前,同じ型の数値データが複数ある場合,
int型あるいは
double型の配列を使ったのと同じである.
文字型の配列を使うときには,次のように宣言する.
char hoge[10];
これで,10個の文字を格納できるメモリーの領域が確保できる.しかし,実際に入れるこ
とができる文字数は,9文字である.文字列の最後に,文字列終了の記号
('\0')を入れるため,1文字分少なくなる.これは,アスキーコードの0番
のNUL
4 のことである.図
2が文字
列"Akita"を文字型配列に格納するイメージである.
図 2:
文字型の配列hoge[10]を用意して,それに"Akita"を格納.一つの箱には,
一つの英数字しか入れられない.そして,最後に\0が入る.
|
以下に示すような方法で,この文字型の配列に文字を格納することができる.
教科書 [
1]のp.251のように,配列の要素毎に文字を入れ
ることができる.
hoge[0]='A';
hoge[1]='k';
hoge[2]='i';
hoge[3]='t';
hoge[4]='a';
hoge[5]='\0';
最後にヌル文字'\0'を入れなくてはならない.実際,この方法で文字を代
入することはまれである.文字列のある特定の要素を操作するには有効である.
変数宣言とともに文字型の配列を初期化することができる.こうすると,配列
hoge[]には
"Akita\0"が格納される.
char hoge[]="Akita";
文字列を操作する関数を用いて,配列に文字を代入することができる.これは,教科書
[
1]のp.252に書いてある方法である.具体的には,次の
ようにする.
strcpy(hoge, "Akita");
これで,配列
hoge[]に文字列
"Akita \0"が格納できる.ただ,この方法を
使う場合は,プログラムの最初に
#include <string.h>とヘッダーファイルをイン
クルードする必要がある.
この間数を使うとディスプレイ出力と同じように文字型の配列に代入できる.
sprintf(hoge, "Akita");
これで,配列
hoge[]に文字列
"Akita \0"が格納できる.
printf()や
fprintf()関数とよく似ている.これを上手に使うと,いろいろな
文字列の格納が可能である.例えば,整数型の変数
nenに2007 が格納されていたと
する.次のようにすると,文字型の配列
fuga[]には,文字列
"Year=2007\0"が格納される.
sprintf(fuga, "Year=%d",nen);
最後に余談であるが,ポインターというものを使えば,次のようなこともできる.簡単な
文字列を代入したい場合は,
sprintf()関数よりも手軽である.
#include <stdio.h>
int main(void){
char *hoge; /* 文字型のポインターを用意 */
hoge="Akita"; /* 代入 */
printf("%s\n",hoge); /* 表示 */
return 0;
}
ポインターを使っても,
hoge[0]とか
hoge[3]のように要素毎に取り扱うことが
可能である.ただし,代入はできない.ポインターについて
は,9章で学習するので,ここでは,こんな方法もあるのかという程度のことで良い.
文字型配列に文字列を格納する方法を示したが,これら以外の方法も存在するであろ
う.sprintf()関数とポインターを使う方法がお勧めである.
表示まで含めた文字型配列を使ったプログラムは,次のようになる.配列に格納された文
字列を表示させるためには,変換指定子
%sを用いる.
sは,string(ひも,
一続き)の略であろう.
#include <stdio.h>
int main(void){
char hoge[10]; /* 文字型の変数 */
sprintf(hoge, "Akita"); /* 代入 */
printf("%s\n",hoge); /* 表示 */
return 0;
}
配列を使う場合,そのサイズはプログラマーが決めなくてはならない.
そのサイズを超えて,代入をするような操作をすると,エラーメッセージを出して止まる.
あるいは,コンピューターがクラッシュすることもあり得る.従って,通常プログラムを
作成するときには,十分大きい配列を用意するのが普通である.
配列のサイズを超えた場合,実際の動作は処理系に依存する.通常は,「segmentation
fault」あるいは「セグメンテーション違反です」とかのメッセージを出して,プログラ
ムは止まる.
文字型の場合,それに格納できるデータは1バイトである.一方,日本語の場合,文字は2
バイトで表現する.文字型が2バイトであれば問題ないのであるが,コンピューターを発
展させたのが米国であるため,仕様は1バイトになってしまった.そこで,日本語を扱う
場合,少しばかり考えなくてはならない.
この問題を解決するために,日本語では2個の文字型のデータ領域に1個の日本語の文字を格納して
いるのである.なんか,「泥縄式」の解決法に思えるが,実際そうなっているのである.
結構,コンピューターの世界もいい加減である.文字型の配列hoge[]に文字列"秋田
"を格納した場合,図3のようになる.hoge[0]と
hoge[1]の2バイトを使って"秋",hoge[2]とhoge[3]で"田",
hoge[0]に"\0"を格納している.
日本語は2バイトでひとつの文字を表すため,hoge[0]='秋';のような代入はできな
い.これには注意が必要である.
図 3:
文字型の配列hoge[10]を用意して,それに"秋田"を格納.日本語の場合,
2つの箱で1つの文字が入る.そして,最後に\0が入る.
|
実際に,文字型の配列に日本語の文字を格納する方法は,アルファベットとほとんど同じ
である.
char bar[]="秋田"
strcpy(hoge,"秋田"); // char hoge[10]; のように宣言
sprintf(fuga,"秋田"); // char futa[10]; のように宣言
foo="秋田"; // char *foo のように宣言
表示方法もアルファベットと同じである.ただし,変換指定子の
%cが使えないこと
には注意が必要である.
#include <stdio.h>
int main(void){
char hoge[10];
sprintf(hoge, "秋田");
printf("%s\n",hoge);
return 0;
}
ここでも,配列を使うため,そのサイズに気を付ける必要がある.ア
ルファベット同様,余裕を持って,配列を確保しなくてはならない.ただし,アルファベッ
トと異なり日本語の場合,文字数の2倍と文字列の終わりを示す
\0が格納できる
サイズが少なくとも必要である.
ホームページ:
Yamamoto's laboratory著者:
山本昌志
Yamamoto Masashi
平成19年1月25日