Comments
Description
Transcript
文字と文字列の処理
2016/06/24 プログラミング演習Ⅰ 第 11 回 文字と文字列の処理 今日の目標:基本的な文字列処理を実行してみる。 1. 文字列(教科書 p.45) 文字列は C 言語では文字型の配列として扱う。文字列はその終わりを示すために最後に 0(文字 表記では’\0’,ヌル文字、終端文字)を暗黙で必ず最後に挿入する。よってヌル文字のために長 さは 1 文字分長くなる。このため、配列の長さはこの分余裕を持って確保しておく。 宣言・使用例: #include <stdio.h> int main(void) { char a[5] = “abcd”;/* 長さ 4 文字だが、終端文字ように更に 1 文字 */ printf(“%s\n”, a); return 0; } この例では、配列 a には以下のように文字が格納される。 a[0] ← ‘a’ a[1] ← ‘b’ a[2] ← ‘c’ a[3] ← ‘d’ a[4] ← ‘\0’ 注意:文字と文字列定数の区別 文字定数は’(シングルクオート)、文字列定数は“(ダブルクオート)で囲む。 例: ‘a’(a 一文字)、‘\n’(改行文字) “abcde”(文字列 abcde+ヌル文字) 2. 文字列処理 C 言語では文字列処理の演算は用意されていない。文字列処理専用の標準関数を使用する。 例: strcpy(コピー先文字列,コピー元文字列):文字列のコピー strlen(文字列):文字列の長さ計算。ヌル文字は長さに入らないことに注意! strcat(連結先文字列,連結元文字列):連結先文字列の最後に連結元文字列を連結して、一つ の文字列にする strcmp(被比較文字列、比較文字列):文字列を比較 など。これらは string.h に定義されているので、インクルードを忘れずに。 以下、基本的な使用例をいくつか示す。 (1)文字列のコピー(プログラム例1) #include <stdio.h> #include <string.h> #define STRLEN 20 /* 文字列配列の長さ*/ int main(void) プログラミング演習第 11 回 1 2016/06/24 { char a[STRLEN], b[STRLEN]; strcpy(a, “abcde”); /* 文字配列 a に abcde+\0 をコピー */ strcpy(b, a); /*a の中身を b にコピー */ printf(“a= %s, b = %s\n”, a, b); /* 文字配列中身の出力 */ return 0; } (2)文字列長の計算(プログラム例 2) #include <stdio.h> #include <string.h> #define STRLEN 20 /* 文字列配列の長さ*/ int main(void) { char a[STRLEN]; int n, m; strcpy(a, “abcde”); /* 文字配列 a に abcde+\0 をコピー */ m = strlen(a); /*a の文字列長を m に代入 */ n = strlen(“abcde”); /*文字列定数”abcde” の文字列長を n に代入 */ printf(“m = %d, n = %d\n”, m, n); /* 文字列長の出力 */ return 0; } (3)文字列の連結(プログラム例 3) #include <stdio.h> #include <string.h> #define STRLEN 20 /* 文字列配列の長さ*/ int main(void) { char a[STRLEN], b[STRLEN]; strcpy(a, “abcde”); /* 文字配列 a に abcde+\0 をコピー */ strcpy(b, “fghij”); /* 文字配列 b に fghij+\0 をコピー */ printf(“a= %s, b = %s\n”, a, b); /* 文字配列中身の出力 */ strcat(a, b); /* 文字配列 a の後に b を連結し abcdefghij +\0*/ printf(“a+b= %s\n”, a); /* 連結文字配列中身の出力 */ return 0; } (4)文字列の比較(プログラム例 4) #include <stdio.h> #include <string.h> #define STRLEN 20 /* 文字列配列の長さ*/ int main(void) { char a[STRLEN], b[STRLEN]; プログラミング演習第 11 回 2 2016/06/24 strcpy(a, “abcde”); /* 文字配列 a に abcde+\n をコピー */ strcpy(b, “fghij”); /* 文字配列 b に fghij+\n をコピー */ printf(“a= %s, b = %s\n”, a, b); /* 文字配列中身の出力 */ if (strcmp(a, b) == 0) { printf(“Same string\n”); } else { printf(“Different string\n”); } return 0; } 3. 本日の演習 (1) プログラム例1~4を入力し実行し,その処理を理解せよ。 (2) 自分の苗字と名前をキーボードから別々に入力し、それらを連結して一つの文字列とし, 表示せよ。苗字と名前の間にスペースを入れること。文字列の入力は下記の例のようにす れば良い。 文字列入力の例: char a[20]; ... scanf(“%s”, a); ... 表示例: $ lab11_2.exe[Enter] Enter last name: Kondo[Enter] Enter first name: Kazuhiro[Enter] Welcome Kazuhiro Kondo $ (3) 任意の文字列をキーボードから入力し、その長さを計算して表示せよ。入力は英数字(半 角)のみとする。文字列の長さは標準関数 strlen を用いて計算せよ。 表示例: $ lab11_3.exe[Enter] Enter a string: 1234ghij[Enter] String length = 8 $ (4) (3)で作成したプログラムを改良し、”exit”と入力されるまで任意の英数字(半角)入 力に対して繰り返し文字列長を表示し、”exit”と入力された時点で終了せよ。入力文字 列を”exit”と strcmp を使って比較し、等しい場合は終了せよ。入力と文字列長計算、 表示は無限ループとせよ。 表示例: $ lab11_4.exe[Enter] Enter a string: 1234ghij[Enter] String length = 8 Enter a string: abcdefg[Enter] String length = 7 Enter a string: exit[Enter] $ プログラミング演習第 11 回 3 2016/06/24 (5) (4)で作成したプログラムをさらに改良し、任意の英数字(半角)入力それ以前の入力の 後に付け加え、全体の文字列、その長さと消去されるまで残り文字数を表示し、”clear”と 入力されるか、文字列長が 30 を超えた時点で文字列全体を消去せよ。このとき、文字列 を消去したことを明示することとする。”exit”と入力された時点で終了せよ。文字列入力 およびその処理は”exit”と入力されるまで無限ループとせよ。 文字列を消去(空に初期化)するには strcpy(a, “”); または a[0] = ‘\0’; とするとよい。 表示例: $ lab11_5.exe[Enter] Enter a string: 1234ghij[Enter] String = 1234ghij, Length = 8, Remaining = 22 Enter a string: abcdefg[Enter] String = 1234ghijabcdefg, Length = 15, Remaining = 15 Enter a string: clear[Enter] String cleared Enter a string: exit[Enter] $ (6) (発展)余裕がある人は挑戦してください。 (4)のプログラムを改良して、以下の簡単な文字列処理システムを構築せよ。 いずれかのコマンドを受け付け、コマンドに応じた文字列処理を行なう。 enter: キーボードから文字列を入力し配列に格納する。もし前に文字列を入力してあ れば上書きする。 print: 配列にある文字列を表示する。もし入力がない場合は空白のみ表示する。 length: 配列内の文字列の長さを計算、表示する。 ?: コマンド一覧を表示する。 exit: プログラムを終了する。 このリストにないコマンドが入力された場合、警告を表示し、改めてコマンド待ちとす る。 表示例: $ lab11_6.exe[Enter] Command? print[Enter] Command? ?[Enter] Commands: enter, print, length, exit Command? hyouji[Enter] Invalid command Command? enter[Enter] String? 1234ghij[Enter] Command? length[Enter] String length = 8 Command? enter[Enter] String? abcde[Enter] Command? length[Enter] String length = 5 Command? exit[Enter] $ (7) (発展)余裕がある人はさらに挑戦してください。 (6)のプログラムに以下のコマンドを追加せよ。 add: 現在配列に格納されている文字列の後に文字列を連結追加する。 clear: 配列の文字列を消去する。 プログラミング演習第 11 回 4 2016/06/24 表示例: $ lab11_7.exe[Enter] Command? enter[Enter] String? 1234[Enter] Command? print[Enter] 1234 Command? add[Enter] String? abc[Enter] Command? print[Enter] 1234abc Command? clear[Enter] Command? print[Enter] Command? exit[Enter] $ (5)と、できた人は(6)、または(7)の各リストと、実行時の表示印刷(script 使用)を提出 せよ。 提出期限は来週水曜(6/29)16 時までとします。電情系事務室(7 号館 2 階 221 号室)外のプ ログラミング演習用メールボックスに提出してください。 注意:提出レポートで明らかに動作しないプログラムは再提出してもらうので、十分デバッグ、 動作確認すること。再提出、期限外はその度に評価を1ランク下げるので、注意。また、未提出、 ならびに再提出を未提出のものは 0 点とする。学生番号、氏名、出題日、課題番号を各プログラム 第 1 ページ先頭にコメント行を使って明記のこと。複数枚にわたる場合はホチキス等でとめること。 簡単な課題なので、必ず自分で演習に取り組むこと。 プログラムにはコメントを十分記入し、インデント、改行を適当に入れて読みやすいプログラム記入 を心掛けること。 動作しないプログラム、指示どおりの機能しないプログラムの他、適切なコメントやインデント のない提出プログラムも再提出の対象となるので注意。 前回再提出となった課題の期限も来週水曜(6/29)の 16 時とします。再提出とされた元のレポー トの上に修正したレポートを一緒に綴じて提出のこと。今週のレポートと再提出のレポートは一 緒に閉じないこと。 4. 来週の予習 教科書(明快入門C)の第 3.20、21 節(p.45-49)、11.79、80 節(p.200-204)の文字列、 文字列処理に目を通しておくこと。 プログラミング演習第 11 回 5