◎第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. 単語数のカウント 単語をアルファベットだけからなる文字列として 文字列中の単語数を数えるプログラム (ヒント:文字列を順番にアルファベットかどうかを調べて、 非アルファベットからアルファベットに変化した回数を しらべればよい。) もっとヒント 一覧へ