◎第8回 文字データの扱い
◇下へ・一覧へ
○テキスト
4章(4.1)
◇下へ・上へ
・文字の表現
文字:数値に置き換える : 文字コード : 規格
文字情報の送り手と受け手でコード体系がちがうと
「文字化け」が生じる。
英数字英記号 ASCII 7ビット(0-127)
( 7ビットであるが、多くの場合データの最小処理単位は
8ビット=1バイト byte なので、C言語では 8ビット整数の char で表す。 )
ASCII符号表(psfile)
制御文字(16進数)
Caridge Return(0D) / Line Feed(0A) / Tab(09) / BelL(07) /
Form Feed(0C) / ESCape(1B) / BackSpace(08) / DELete(7F)
ASCII' + カナ = JIS 8単位 -> 8ビット char ( unsigned char )
(8ビットのこと)
ここで ASCII' は JIS-ROMAN(JIS 英数字)のことで、ほとんど ASCII と同じ
なので、この様に表記した
コード 0x5C は、ASCII では、逆斜線であるが、JIS-ROMAN では、
円記号である。一般にはプログラムはコードだけを見るので、
両者は区別されない。
漢字を含めて 8(7)ビット+8(7)ビット 16ビット 英数字 2文字分(2バイト)
英数字と漢字の混在 : JIS漢字 (切換えコード) ASCII (切換えコード)
切換えコードは不便
unix 方式 EUC : JIS漢字+128..... ASCII
( JIS漢字+128 は 漢字を表す JIS 2バイトコードのそれぞれのバイトに
128 を加算する(最上位ビットを1にする)ことで、ASCII と区別して
切換えコード無しに混在可能にする )
パソコン方式 シフトJIS : ( SJIS )
( JIS漢字の 第1バイトの 7ビットのうち約6ビットを カナ文字を含む
JIS 8ビットコードの未使用部分にわりあて、SJIS 第1バイトとし、
残りのビットをJIS 漢字第2バイトともに SJIS 第2バイトにする。
SJIS 第2バイトは、JIS 8単位やASCII と重複するが、第1バイトで
区別できる )
切換え方式(いわゆる JIS)メールなど (7bitでOK:多国語OK:処理が複雑)
EUC 処理がもっとも容易 (8ビットのJIS との混在ができない)
SJIS 処理がやや容易 (8ビットのJIS との混在可能)
◇下へ・上へ
文字型 C では、char 1バイト(8ビット)整数 普通は文字コード
Cのプログラム中で 'a' と書くと、「aのコード」を意味する。
例: 変数宣言,代入,演算
char x;
int i;
x='B'; /* 変数 x に 文字 B のコードが入る。
B のコードは42(16進数)なのでこの場合、
16進数で x=0x42; あるいは 10進数で x=66;
と書いても同じであるが、'B' の方が人間に
は分かりやすい */
i=x-'A'+1; /* 変数 i に変数 xの値(42:16進数)から
文字 A のコード(この場合41:16進数)を
引き算し、1を加えたた値(この場合2)が入る。
AからZまでの文字コードは連続した数値なので、
これにより、x が大文字アルファベットである
場合は何番目の文字であるかが計算できる。
(j番目の大文字のコードを計算するにはどうすれば
よいか?)
*/
if( x>='A' && x<='Z' ){
/* 変数 x の値が文字 Aのコードより以上であり
かつ 変数 x の値が文字 Zのコードより以下
であれば if の条件は真となる。
AからZまでの文字コードは連続した数値なので、
これが真ならば x は大文字と判断できる。
&& は論理積(logical and)を意味する
*/
printf("upper case letter\n");
}
小文字 a から z までもまた連続しているが、
大文字とは離れているので、アルファベットであるかどうかを
判定するにはもう少し複雑な判断が必要である。
◇下へ・上へ
文字列型 表現が難しい 長さ と 文字コード列
文字コード列 と 終了コード
C では文字列は char の配列であり コード 0 が終了コード
Cのプログラム中で "abc" と書くと、
メモリ中に4つの要素をもつ char 変数の列(配列)が確保され
順に aのコード、bのコード、cのコード、0 が格納される。
この "abc" は次に示す s とほぼ同じである。
char s[4];
s[0]='a';/* C言語では添字は 0 から始まる。*/
s[1]='b';
s[2]='c';
s[3]=0; /* これは 配列 s の最後の要素 */
Cのプログラム中で制御文字を文字や文字列に含める時は、次のように表記する。
caridge return (\r): 印字位置を左の端に戻す(復帰)
line feed(\n) : 改行。行送り。印字位置を次の行に移す。
tab(\t) : タブ。印字位置を次の欄に移す。
(次のタブストップ設定位置。
タブストップは8桁毎に設定されていることが多い)
formfeed( \f ) : 改ページ。ページ送り。用紙送り。
印字位置を次のページに移す。
backspace(\b) : 後退。印字位置を1文字分前に戻す。
( alert (\a) : 警告音。ベル。新しい C での記述法 )
Cのプログラム中で "a\n" と書くと、
メモリ中に3つの要素をもつ char 変数の列(配列)が確保され
順に aのコード、line feedのコード、0 が格納される。
他に文字コードを書く時は、\ のあとに 8 進数(3桁)で書くことが
できる。(混乱が生じない限り桁数が少なくてもよい)
\ そのものを含める時は \\ と書く。
文字列中に " を含める。 \"
文字定数中に ' を含める。\'
\ の次に上記以外の文字が来る時は、その文字そのままを意味する。
コード 0x5C は、ASCII では、逆斜線であるが、JIS-ROMAN では、
円記号である。一般にはプログラムはコードだけを見るので、
両者は区別されない。
例: char x, y;
x='\n'; /* 変数 x に改行のコードを代入する */
y='\''; /* 変数 x にアポストロフィのコードを代入する */
例: "\"abc\"\n" は
「ダブルコーテーション」,「a」,「b」,「c」,
「ダブルコーテーション」,「改行」からなる文字列を表す。
文字列なので記憶装置にはさらに終わりのコードが入っている
◇下へ・上へ
注意事項
unix のファイル中では、linefeed '\n' を「行の終り」の印として用いる。
msdos などのファイル中では、CR LF "\r\n"' を「行の終り」の印として用
いる。
unixでは、画面表示のときは、\n を \r\n に自動的に変換している。また、
入力の時は、Return キー に対応する \r を \n に自動的に変換している。
例
1. 文字列の長さを求める。
文字型配列 a[2000]; に文字列を入力し、その長さを求める。
strlen.c( PAD psfile)
漢字は2文字と数えられてしまう。
2. 文字列のコピー
文字型配列 a[2000] に文字列を入力し、b[2000] にコピーする。
(2000 全部コピーするのは無駄である)
strcpy.c( PAD psfile)
(これらは、strlen / strcpy として標準的に使える)
3. 文字列中の大文字(A-Z)の数をを数えるプログラム。
uccount.c( PAD psfile)
4. 文字列の比較(辞書式とは少し違う)
strcmp.c( 擬似コード)
(これは、strcmp として標準的に使える)
◇下へ・上へ
○演習
1. 文字列中の数字(0-9)の数をを数えるプログラムを作れ。
2. 文字列数値変換
a)文字列が数字だけからなると仮定し、「数字の数値」
(コードではない)をすべて加算するプログラムを作れ。
例えば文字列 '1997' を与えた時に 1+9+9+7 を計算し
26 を求め、表示する。
ヒント: '0'から '9'まではコードで、順に並んでいるので
文字(char)から'0' を引くと「数値」になる。
b)文字列が数字だけからなると仮定し、その数字の列が
10 進数として、その数値を整数型変数 n に格納する
プログラムを作れ。
( scanf("%d",&n)の内部ではこのようなことが
行なわれている )
◇一覧へ・上へ
○レポート課題(解答)
次のプログラムを作れ。アルゴリズムを PAD または、擬似コードで説明し、
実行結果を添付せよ。
1. 文字列中の小文字(a-z)の数を数えるプログラム
2. 単語数のカウント
単語をアルファベットだけからなる文字列として
文字列中の単語数を数えるプログラム
(ヒント:文字列を順番にアルファベットかどうかを調べて、
非アルファベットからアルファベットに変化した回数を
しらべればよい。)
もっとヒント
一覧へ