文字と文字列
文字
C言語における文字とは,文字型変数に格納可能なデータを意味する.文字型変数の型名はcharである.char型は,1バイトのサイズを持ち,格納できる値は-128〜127までの整数である.表 1にC言語で利用可能な変数の型の一部を示す.
| 種類 | 型名 | サイズ(Byte) | 値の範囲 |
|---|---|---|---|
文字型 |
|
1 |
-27 〜 27-1 |
整数型 |
|
2 |
-215 〜 215-1 |
|
4 |
-231 〜 231-1 |
|
|
8 |
-263 〜 263-1 |
|
浮動小数点型 |
|
4 |
1.175494×10-38 〜 3.402823× 1038 |
|
8 |
2.225074×10-308 〜 1.797693×10308 |
|
|
16 |
3.362103×10-4932 〜 1.189731×104932 |
文字型に格納可能な値と,ファイルに記録あるいは画面に表示される文字との対応関係を定めたものがASCIIコードである.表 2にASCIIコードを示す.0番から31番までは制御コードであり,画面に表示されないことに注意.
0 |
|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
文字型変数に値を代入し,printf 関数によって表示するサンプルソースコードをリスト 1に,また,その実行結果をリスト 2に示す.printf関数での書式指定によって,変数の中身を文字として表示するか,数値として表示するかを制御できることが分かる.
char a, b;
a = 65;
b = 'A';
printf("char: %c %c\n", a, b);
printf("value: %d %d\n", a, b);
A A
65 65
文字列
文字列とは文字の集合体である.では,char 型の値(すなわち,文字)の集合体はどのように定義するのだろうか.C言語では同じ型の値の集合体を定義するための,配列(array) と呼ばれるデータ構造が用意されている.以下では,文字列を定義するための配列の利用方法について解説する.
|
配列についての一般的な内容は次回で学習する. |
文字列を定義するためには,文字型変数の配列を宣言する.配列の宣言には,配列の要素数を予め決定し,明示する必要がある.例えば,10文字からなる文字列nameを宣言するには,
char name[10];
と記述する.この宣言によって図 1のように,char型の値を10個格納するため領域が,メモリ上に確保される.
配列の各要素には0から始まる添字と,大かっこを用いてname[3]のようにアクセスできる.添字には定数以外にも,整数式を用いることができる.例えば
int i = 1;
char a[30];
a[2*i+1] = 'A';
などと記述することができる.なお,宣言直後の配列の中身はランダムな値が入っているため,初期化することが望ましい.配列の初期化の典型的なパターンをリスト 3に示す.
char data[20];
int i;
for (i = 0; i < 20 /* 配列の要素数 */; ++i) {
data[i] = 0;
}
図 1の配列に,Takushokuという単語をキーボードから入力するには
scanf("%s", &name[0]);
と記述する.scanfの第2引数には,キーボードからの入力を格納する変数のアドレスを与えるが,ここではnameという配列の先頭の要素を指すアドレスを与えていることがわかる.配列の先頭アドレスの省略形として配列名を使うこともできる.
|
次回で学習する多次元配列ではこの限りではないので注意. |
すなわち,省略形を使う場合には,
scanf("%s", name);
と記述する.
キーボードからTakushokuと入力した直後のメモリの中身は図 2のようになっている.
最後の要素にキーボードからの入力ではない\0が挿入されていることがわかる.この\0は文字列の区切りを表すためのシンボルであり,null記号と呼ばれる.したがって,配列の宣言時には,想定される文字数の最大値+1を配列の要素数とする必要がある.\0の役割は,要素数よりも短い文字数の単語が入力された場合に,その単語の終わりを示すことである.
ファイル入出力
プログラム内でデータファイルを読み書き,すなわち入出力を行うためには,ファイルのオープンおよびクローズ処理が必要となる.
ファイルのオープン
ファイルをオープンするためには,fopen関数を用いる.基本的な使用方法は以下のとおりである.
FILE *fp; // ファイルポインタ
fp = fopen("ファイルのパス\ファイル名", モード);
- ファイルポインタ
-
オープン後のファイルからデータを読み込んだり,あるいはファイルにデータを書き込む際に,ファイル名の代わりに使う識別子のようなもの.
- モード
-
オープンしたファイルからデータを読み込むときには
"r",ファイルにデータを上書きするときには"w",追記するときには"a"を用いる.また,データの格納形式はバイナリ形式の際には"rb", "wb"のようにbを追加する.
ファイルから1文字を読み込む
オープンしたファイルから1文字を読み込むにはgetc関数を用いる.使用例をリスト 4に示す.
int c;
FILE *fp = fopen("myData.txt", "r");
do {
c = getc(fp);
printf("%c", c);
} while (c != EOF);
fclose(fp);
ここで,6行目のc != EOFについて解説する.EOFはEnd of Fileの略であり,ファイルの終端を示す特別な値である.EOFの値は,コンパイラによって異なってもよいことになっており,char 型の範囲外の値も取りうるため,getc関数はint 型の値を返す仕様となっている.
|
本講義で用いるコンパイラではEOFの値は-1を取る |
文字検査関数
ファイルから読み込んだ文字の種類を判別する必要が生じることがある.たとえば,その文字が数字なのか,アルファベットなのか,アルファベットなら大文字なのか,小文字なのか,といった具合である.この判別を可能とするのが文字検査関数である.文字検査関数を使用するにはctype.hをインクルードする必要がある.
リスト 5に,文字が10進数の数字かどうかを判別するisdigit()関数の使用例
を示す.
#include <ctype.h> //文字検査関数のために必須
#include <stdio.h>
int main() {
int c;
FILE *fp;
fp = fopen("myText.txt", "r");
c = getc(fp);
if (isdigit(c)) {
printf("読み込んだ文字%cは数字です.\n", c);
} else {
printf("読み込んだ文字%cは数字では有りません.\n", c);
}
fclose(fp);
}
すべての文字検査関数はその引数にint型を取る.isdigit関数においては,引数の文字が10進数の数字であったときに,非ゼロの値が,10進数の数字ではなかったときにゼロが戻り値となる.以下に,文字検査関数の一覧を示す.
isalnum
|
文字がアルファベットもしくは数字かどうか |
isalpha
|
文字がアルファベットかどうか |
isblank
|
文字が標準ブランク文字かどうか |
iscntr
|
文字が制御文字 (control character) かどうか |
isdigit
|
文字が10進数の数字かどうか |
isgraph
|
文字が空白 (' ') を除く表示文字 (printing character) かどうか |
islower
|
文字がアルファベットの小文字かどうか |
isprint
|
文字が表示文字かどうか |
ispunct
|
文字が区切り文字 (punctuation character) かどうか |
isspace
|
文字が標準空白類文字かどうか |
isupper
|
文字がアルファベットの大文字かどうか |
isxdigit
|
文字が16進数の数字かどうか |
文字列処理関数
string.hをインクルードすることで文字列を操作するための標準関数
が使えるようになる.そのうち,よく用いられる関数について以下で説明する.
strcmp-
文字列の比較を行う.2つの文字列があり,その先頭アドレスを
s1とs2とするとき,
if (strcmp(s1, s2) == 0) {
:
のように用いる.この関数はs1の中身のASCIIコード < s2の中身のASCIIコードならば負の値,s1の中身のASCIIコード == s2の中身のASCIIコードならばゼロ,はs1の中身のASCIIコード > s2の先中身のASCIIコードならば正の値を返す.これを用いて例えばアルファベット順での順位の比較などを行うことができる.
strcpy-
文字列のコピーを行う.コピー元の文字列の先頭アドレスを
src,コピー先の文字列の先頭アドレスをdstとするとき,
strcpy(dst, src)
のように用いる.終端記号\0までコピーされる.コピー先のアドレスで示される領域とコピー元の領域に重なりがある場合,この関数の動作は未定義であるため,使用には注意を要する.
この他にもmemcpy, memmove, memsetなどよく使われる関数があるが,ここでは説明を割愛する.