Lecture 8 配列(2)文字と文字列

配列(2)「文字と文字列」の解説動画

昨年度の講義(昨年度は第7回として実施)の録画を,以下に載せました.聞き逃した人はこちらを確認してください.




文字

コンピュータ内部は,「0」と「1」の二進法の世界で,そのまま文字として扱うことが出来ません. では,どのように文字を表現しているのでしょう?  コンピュータでは,「文字コード」を使って英数字をぞれぞれの番号に対応させて管理しています.

例えば,下のASCIIコード表をよく見て下さい. 文字コードを表現するには16進数を用いるのが便利です. 下の表では,横が16進数の2桁目,縦が16進数の1桁目を表し,赤字で10進数の値を表記しています. 例えば大文字の「A」は,16進数では「0x41(0xは16進数という意)」,10進数では「65」で表されます.
これらを覚える必要はありませんが,いくつかの特別な意味を持つ文字コード(0x0から00x20までの文字には特別な意味が割り当てられています). 例えば,0x00(NUL)はヌル文字,0x0D(CR)や0x0A(LF)は改行などを知っておくと良いでしょう.



【文字コード表】

00 10 20 30 40 50 60 70
0 NUL 0 DLE 16 SP 32 0 48 @ 64 P 80 ` 96 p 112
1 SOH 1 DC1 17 ! 33 1 49 A 65 Q 81 a 97 q 113
2 STX 2 DC2 18 " 34 2 50 B 66 R 82 b 98 r 114
3 ETX 3 DC3 19 # 35 3 51 C 67 S 83 c 99 s 115
4 EOT 4 DC4 20 $ 36 4 52 D 68 T 84 d 100 t 116
5 ENQ 5 NAK 21 % 37 5 53 E 69 U 85 e 101 u 117
6 ACK 6 SYN 22 & 38 6 54 F 70 V 86 f 102 v 118
7 BEL 7 ETB 23 ' 39 7 55 G 71 W 87 g 103 w 119
8 BS 8 CAN 24 ( 40 8 56 H 72 X 88 h 104 x 120
9 HT 9 EM 25 ) 41 9 57 I 73 Y 89 i 105 y 121
A LF 10 SUB 26 * 42 : 58 J 74 Z 90 j 106 z 122
B VT 11 ESC 27 + 43 ; 59 K 75 [ 91 k 107 { 123
C FF 12 FS 28 , 44 < 60 L 76 \ 92 l 108 | 124
D CR 13 GS 29 - 45 = 61 M 77 ] 93 m 109 } 125
E SO 14 RS 30 . 46 > 62 N 78 ^ 94 n 110 ~ 126
F SI 15 US 31 / 47 ? 63 O 79 _ 95 o 111 DEL 127

シングルコーテーション「'」の意味

一つの文字を,シングルコーテーションで囲むと,ASCIIコードになります. 例えば,
char x = 'A';

char y = 0x41;

char z = 65;
これらはすべて同じものです!!!

やってみよう

  • 文字コードを数字でプリントしてみよう.
  • 大文字を小文字に変換してみよう.




文字列

文字列は配列の一種で,その要素は文字のキャラクタコードである. Cは,他の言語と異なり,組込みの文字型や文字列型というものが存在しない. Cでよく文字を格納するのに用いられる char型は,その名前から「文字型」であると思われがちであるが,それは誤りである. char型は,単なる「8ビット整数型」であるに過ぎない. このため,C言語では,文字として単純に asciiコードを用い,文字列の終端には,ヌル文字(null character) を置くことで文字列の終端を認識させている.

* 半角文字の場合はASCIIコード.全角文字の場合は多くのコード体系が混在している.これが文字化けの起こる理由である.ここでは半角のみ取り扱う.

ヌル文字

数値の0のこと.文字として '\0' と書くこともある.

文字定数を用いて,文字列を作成する場合,
    char* str = "Meiji University";
のようにダブルコーテーションで括って書く.ダブルコーテーションで括られた文字列が持つ値は,その文字列が格納される場所のアドレスである.従って,str には(文字コードなどではなく)アドレスが代入される. また,Meiji University の文字数は 16文字である(ホワイトスペースも文字である)が,実際には 最後の y の後にヌル文字が自動的に追加されて 17文字になる. このため,この文字列を格納する配列を宣言するときには,最低でも17文字以上の領域が必要になる.
    char s[20];				// 最低でも17文字以上必要
    strcpy(s,"Meiji University");	// char型の配列sに文字列17文字分をコピー

代表的な文字列操作関数

以下はすべて,string.h で定義されている文字列操作関数である.

strcpy

既に上の例で使用したが,文字をコピーする関数である.destinationに既に文字が入っている場合は,sourceの文字数分塗りつぶされる.返り値は作成された文字列への参照.
char* strcpy(char* destination, const char* source);

strcat

文字列を追加する関数.はじめにdestinationに入っている文字の後に文字列を追加する.返り値は作成された文字列への参照.
char* strcat(char* destination, const char* source);

strcmp

2つの文字列を比較する.返り値は,s1>s2で正の値,s1==s2で0,s1<s2で負の値.
int strcmp(const char* s1, const char* s2);

strlen

文字列の長さを返す.このとき,最後のヌル文字は長さに含まないので注意.
int strlen(const char* s);


文字の数字を「数値」に変換する

asciiコード表を利用する

asciiコード表を見ると,文字の0は,0x30であり,その後数値が増えるに従い1ずつ増えていく. これを利用すると,文字としての数字と数値との間で変換ができる.
    int ix = 3;
    char cx = '0'+ix;	// 数値を文字に変換
    printf("%c\n",cx);

atoi

複数桁の数字文字列を数値に変換するには,atoiを用いると良い.
    #include <stdlib.h>
	char nstr[] = "123";
	int  x = atoi(nstr);



Quiz 8(第8回の提出課題ではありません)

以下の問それぞれに対応するプログラムを作成しなさい.

    1. 文字をキーボードから入力して,配列 str[ ] に格納する関数, 入力された文字列 str[ ] を画面に表示する関数,および,str[ ] 中の文字数を カウントする関数をそれぞれ作成し,以下のプログラムを完成せよ. なお,main 関数は以下の通りとし,変更しないこと.
      int main(void)
      {
          char str[100];
      
          input(str);   // キーボードから入力された文字列をstrに移します.
          disp(str);    // strに格納された文字列を画面に表示します.
          printf("文字数は %d です.\n", count(str));
          return 0;
      }
      
      【ヒント】引数の (char* str) は,(char str[ ]) とほぼ同じ意味で,どちらでも使えます.

    2. キーボードから文字を入力した時(英数字,大文字小文字,記号を問わない), 何の文字が何個ずつ使われているかを表示するプログラムを作成せよ.
      //実行例
      > 07-2
      Type a string: ababccc
       a: 2
       b: 2
       c: 3
      
      【ヒント】上の解答例では,ループのスタート文字を'A'にしてしまっていますが, これだと一部の文字や記号しかスキャンされません.たとえばスペース' '(==0x20)から始めて, ティルダ'~' (==0x7E)までスキャンすると,ほぼすべての文字をカウントできます. アスキーコード表をよく見て考えてみましょう.

    3. 以下の表に従い,各科目の平均点と,各個人の平均点を計算して表示するプログラムを作成せよ. 表は,二次元配列の初期化を用いてプログラム中に記入せよ.


    4. キーボードから文字(半角英数字記号)を入力し, それをアスキーコード順に並び替えて画面に出力するプログラムを作れ. 但し,並び替えを行う関数 void sort(char s[ ]) を作成すること.

    5. 【チャレンジ問題】 文字列をキーボードより入力させ,リターンを押すたびに それまで入力した文字列すべてが出力されるようにせよ. "end"の文字列を入力すると,入力を終了し, それまで入力してきたすべての文字列と, その文字列を反転させた文字列が出力されるようにせよ.

      実行例
          > 07-5
          >> abc
          abc
          >> 123
          abc 123
          >> pqr
          abc 123 pqr
          >> end
          abc 123 pqr
          rqp 321 cba
      




Assingment(課題)8


課題の提出は Online Judge にて行います.

  • 提出期限があります.できるだけ早めにやりましょう.
  • Online Judge は普通の課題提出方法とは異なり,良い点が取れるまで何度でも挑戦できます.良い点が取れるまで頑張ってやろう.
  • わからないことは,早めに Teams で聞こう.問題は自分で解決すること.
  • それでもどうしてもわからないときは,毎週月曜日の2時限目にZoomによるオフィスアワーを用意しています. ZoomのリンクはOh-o! meijiで確認してください.
  • Online Judge のページはこちら