240 likes | 355 Views
情報処理 Ⅱ. 2006年12月22日(金). 本日学ぶこと:プログラミングの例題2つ. 暗号化・復号 学ぶこと:構造体の利用,写像としての配列, static 変数 文字列の書き換え 学ぶこと:関数呼び出しによる文字列操作,ライブラリ関数の活用 統合開発環境 (Eclipse). Wagahai Ha Nekodearu. tarako. Sioieid Ei Wyjgayipr. takehiko. IDE. Integrated Development Environment の略, 統合開発環境とも呼ばれる.
E N D
情報処理Ⅱ 2006年12月22日(金)
本日学ぶこと:プログラミングの例題2つ • 暗号化・復号 • 学ぶこと:構造体の利用,写像としての配列,static変数 • 文字列の書き換え • 学ぶこと:関数呼び出しによる文字列操作,ライブラリ関数の活用 • 統合開発環境(Eclipse) Wagahai Ha Nekodearu tarako Sioieid Ei Wyjgayipr takehiko
IDE • Integrated Development Environmentの略,統合開発環境とも呼ばれる. • ハードディスクのIDEは,Integrated Drive Electronicsの略 • エディタ,コンパイラ,デバッガなど,プログラミングに必要なツールが一つのインターフェースで統合して扱えるような環境のこと. • デバッガとは…プログラムの不具合(バグ)の発見や修正を支援するソフトウェア.Linuxではgdbコマンドが利用可能. • IDEの例:Eclipse,Visual C++,Turbo C++ など
Eclipse • オープンソースの統合開発環境 • もともとIBMが開発したもので,現在はEclipse Foundationが開発・管理している. • プラグインにより機能を付加できる. • Javaに限らず様々なプログラミング言語の開発に利用可能 • 情報処理Ⅲで利用されている. • 自宅で使いたい人へ • All-in-one Eclipseがおすすめ • コンパイラ・デバッガは別途インストールしなければならない
暗号化問題 • 仕様 • 入力文にあるすべての'A'をα,すべての'B'をβ,…に置き換えて出力する.(単一換字暗号という.) • 文字は,char型の任意の値とする.ただし'\0'を除く. • どの文字をどの文字に置き換えるかは,プログラムの中で指定する. • 簡単な操作で,復号できるようにする. • Wagahai Ha Nekodearu • Sioieid Ei Wyjgayipr 暗号化 復号
暗号化問題 • (まずい)方針 • 'A'をα,'B'をβ,…に置き換えるのをswitch~caseで行う. • プログラムが無駄に長くなる. • 柔軟性に欠ける. char encrypt_char(char c) { switch (c) { case 'A': return 'D'; case 'B': return 'E'; ... } }
変換前 変換後 'A' 'D' 'B' 'E' ... ... 暗号化問題 • 方針 • 暗号化のための変換表(暗号化表)を,配列で保持する. • char encrypt_table[256]; encrypt_table['A']の値 encrypt_ table … 'D' 'E' 'F' 'G' … +0 +'A' +'C' +1 +'B' +'D' +255
暗号化問題 • 方針(続き) • 暗号化は,写像を用いる. • a = 'A';のとき,b = encrypt_table[a];でbの値が'I'となるようにするには,あらかじめencrypt_table['A']の値を'I'としておけばよい. • 復号のための変換表(復号表)は,逆写像を用いて求める. • char decrypt_table[256]; • decrypt_table[encrypt_table['A']] = 'A'; gがfの逆写像 であるとは, g(f(x))=x
暗号化問題 fが恒等写像 であるとは, f(x)=x • 方針(続き) • 定義する関数 • 変換表を恒等写像にする. • 暗号化表を設定する. • 暗号化表を用いて,復号表を設定する. • 変換表を用いて,文字列を暗号化もしくは復号する. • 暗号化と復号はどう区別する? • 暗号化:./encrypt Wakagai Ha Nekodearu • 復号:./encrypt -d Sioieid Ei Wyjgayipr コマンドラインオプション
定義する構造体 • typedef struct edtable { char encrypt_table[256]; char decrypt_table[256];} edtable; • 暗号化(encryption)と復号(decryption)の表(table) encrypt_table decrypt_table
0 0 1 1 … … 'A' 'A' 'B' 'B' 'C' 'C' … … 255 255 定義する関数(1) • void reset_table(edtable *table); • 変換表を恒等写像にする. table encrypt_ table ? ? … ? ? ? … ? decrypt_ table ? ? … ? ? ? … ?
'I' 'F' 'C' +'A' +'C' +'B' 定義する関数(2) • void set_encrypt_table(edtable *table, const char *from, const char *to); • 二つの文字列を用いて,暗号化表を設定する. encrypt_ table … … table from to … '\0' 'F' 'C' … '\0' 'A' 'B' 'C' 'I'
定義する関数(3) • void set_decrypt_table(edtable *table); • 暗号化表を用いて,復号表を設定する. table decrypt_ table … 'A' … +0 +'A' +1 +'B' +'I' +255 encrypt_ table … 'I' … +0 +'A' +'C' +1 +'B' +'D' +255
定義する関数(4) • char *encrypt(const char *text, const char *table); • 変換表を用いて,文字列を暗号化もしくは復号する. • 「暗号化」と「復号」の処理を共通化している! • 戻り値は,変換された文字列で,static変数result(のポインタ値)となる. text 'W' 'a' 'g' 'a' 'h' 'a' 'i' '\0' table … … result 'S' 'i' 'o' 'i' 'e' 'i' 'd' '\0' static領域(関数が終了しても,破棄されない) 戻り値
暗号化プログラムの補足 • 関数set_encrypt_tableの仮引数from, toはconst char *型である.このとき • ○from++; to++; • × (*from)++; • fromの参照先(const char型の値)を変更しようとしている. • 暗号化のように,関数開始時点で長さがわからない文字列を入力にとり,それと同じ長さの暗号文を返すときは,生成する暗号文が配列領域をはみ出さないように配慮する. • encrypt.cでは,100文字を越える入力は無視している.
文字列書き換え問題 • 仕様 • 3つの文字列を,コマンドライン引数にとる. • 1番目の文字列の中に,2番目の文字列が含まれていれば,それを3番目の文字列に置き換える. • 例 • ./strrep tarako ra kehibefore: tarakoafter: takehiko • ./strrep 'Wakayama City' C Universbefore: Wakayama Cityafter: Wakayama University 「Wakayama City」が一つの引数
文字列書き換え問題 • mainで定義する変数 • char *str_in = argv[1]; • char *str_from = argv[2]; • char *str_to = argv[3]; • argc >= 4 の確認を忘れずに. • char str[256]; • argv[1]のみでは,文字列を伸ばすこと(tarako⇒takehiko)ができない.そこで,strに文字列をコピーして,この配列を書き換える. argv[1] 't' 'a' 'r' 'a' 'k' 'o' '\0' str 't' 'a' 'r' 'a' 'k' 'o' '\0' …
文字列書き換えの関数(1) • char *strrep(char *str, const char *str_from, const char *str_to); str 't' 'a' 'r' 'a' 'k' 'o' '\0' … str_from 'r' 'a' '\0' 書き換えられる str_to 'k' 'e' 'h' 'i' '\0' 書き換えられない
文字列書き換えの関数(2) • 関数内で使用する配列・ポインタ str_from 'r' 'a' '\0' str_to 'k' 'e' 'h' 'i' '\0' str 't' 'a' 'r' 'a' 'k' 'o' '\0' … r str_buf 't' 'a' 'r' 'a' 'k' 'o' '\0' … p q
文字列書き換えの関数(3) • *r = '\0'; str_from 'r' 'a' '\0' str_to 'k' 'e' 'h' 'i' '\0' str 't' 'a' '\0' 'a' 'k' 'o' '\0' … r str_buf 't' 'a' 'r' 'a' 'k' 'o' '\0' … p q
文字列書き換えの関数(4) • strcat(r, str_to); str_from 'r' 'a' '\0' str_to 'k' 'e' 'h' 'i' '\0' str 't' 'a' 'k' 'e' 'h' 'i' '\0' … r str_buf 't' 'a' 'r' 'a' 'k' 'o' '\0' … p q
文字列書き換えの関数(5) • strcat(str, q); str_from 'r' 'a' '\0' str_to 'k' 'e' 'h' 'i' '\0' str 't' 'a' 'k' 'e' 'h' 'i' 'k' 'o' '\0' … r str_buf 't' 'a' 'r' 'a' 'k' 'o' '\0' … p q
文字列書き換え関数の注意点 • 使用しているライブラリ関数 • strcpy:文字列をコピーする※ • strstr:文字列の中から文字列を見つける • strlen:文字列の長さを求める • strcat:文字列を連結(concatenate)する※ • いずれも,第1引数が処理対象の文字列となる. • ※最初の引数は文字配列を指すポインタとし,配列には,文字列をコピー・連結しても大丈夫な領域を持たせておく. • rが文字列の先頭のとき,str_toやqが空文字列のときも,関数strrepで問題なく書き換えられる. • ./strrep Okayama O Wa • ./strrep takehiko kehi ''
今後の予定 • 第12回:2007年1月19日(金) • 授業開始時に第2回レポートを提出すること. • 第13回:1月26日(金) • 第14回:2月2日(金) • 試験:試験期間中に実施する.掲示板を参照のこと. • 「Cの書籍1冊」と「自筆ノート1冊」の持ち込みを認める.