C 言語入門 第 12 週 プログラミング言語Ⅰ ( 実習を含 む。 ), 計算機言語Ⅰ・計算機言語 演習Ⅰ, 情報処理言語Ⅰ ( 実習を含 む。 ) 1.

Slides:



Advertisements
Similar presentations
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
Advertisements

復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
情報処理演習C2 ファイル操作について (2).
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第7回 データの基本型 情報・知能工学系 山本一公
データ構造とアルゴリズム 第10回 mallocとfree
基礎プログラミングおよび演習 第9回
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
第8回 プログラミングⅡ 第8回
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
問題 1 キーボードから入力した数の合計を計算するプログラムを 作成せよ。最初に、何個の数を入力するかその数を入力 するようにする。
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
ファイル操作と文字列の利用.
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
プログラミング論 関数ポインタ と 応用(qsort)
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラミング応用 printfと変数.
プログラミング論 II 2008年10月30日 文字列
Cプログラミング演習 第7回 メモリ内でのデータの配置.
プログラミング 4 記憶の割り付け.
画像処理プログラムの説明.
プログラミング演習I 2003年5月7日(第4回) 木村巌.
第10章 これはかなり大変な事項!! ~ポインタ~
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング入門2 第11回 情報工学科 篠埜 功.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
第7回 プログラミングⅡ 第7回
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
09: ポインタ・文字列 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング基礎B 文字列の扱い.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
フロントエンドとバックエンドのインターフェース
情報処理Ⅱ 第2回:2003年10月14日(火).
プログラミング演習I 2004年5月19日(第5回) 理学部数学科・木村巌.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング基礎a 第6回 C言語によるプログラミング入門 配列と文字列(その2)
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
高度プログラミング演習 (09).
ポインタとポインタを用いた関数定義.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
09: ポインタ・文字列 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
情報処理Ⅱ 2006年11月24日(金).
情報処理Ⅱ 第7回 2004年11月16日(火).
プログラミング論 文字列
プログラミング 4 文字列.
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
8.文字列処理 8.1 C#の文字列 C#では, “ABCD”のように文字列を2重引用符で挟んで指定します。ASCIIコード体系のとき,以下のような内部形式となります。 1 1 文字 ‘A’ ナル文字 1 1 文字 ‘B’ A B C D \ 文字 ‘C’ 1 1 文字 ‘D’ ナル文字‘\0’
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング基礎a 第5回 C言語によるプログラミング入門 配列と文字列
プログラミング入門2 第5回 配列 変数宣言、初期化について
プログラミング演習II 2003年10月29日(第2,3回) 木村巌.
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

C 言語入門 第 12 週 プログラミング言語Ⅰ ( 実習を含 む。 ), 計算機言語Ⅰ・計算機言語 演習Ⅰ, 情報処理言語Ⅰ ( 実習を含 む。 ) 1

文字列の基本 2

2 進数 8 進数 10 進数 16 進数 a b c d e f の桁へ 桁上がり 4 の桁へ 桁上がり 8 の桁へ 桁上がり 16 の桁へ 桁上がり 8 の桁へ 桁上がり 10 の桁へ 桁上がり 16 の桁へ 桁上がり

2 進数 8 進数 10 進数 16 進数 f f fa fb fc fd fe ff の桁へ 桁上がり 256 の桁へ 桁上がり

8bit 整数の 10 進表現 2進2進 進 ABCDEF A B C D E F 下位 4 ビット 5 2 進数と 10 進数は桁数の対応で収まりが悪い

8bit 整数の 2 進表現 2進2進 進 ABCDEF A B C D E F 下位 4 ビット 6 2 進数は桁が多過ぎて直感的に分かり難い

8bit 整数 16 進表現 2進2進 進 ABCDEF a0b0c0d0e0f a1b1c1d1e1f a2b2c2d2e2f a3b3c3d3e3f a4b4c4d4e4f a5b5c5d5e5f a6b6c6d6e6f a7b7c7d7e7f a8b8c8d8e8f a9b9c9d9e9f 1010 A a0a1a2a3a4a5a6a7a8a9aaabacadaeaf 1011 B b0b1b2b3b4b5b6b7b8b9babbbcbdbebf 1100 C c0c1c2c3c4c5c6c7c8c9cacbcccdcecf 1101 D d0d1d2d3d4d5d6d7d8d9dadbdcdddedf 1110 E e0e1e2e3e4e5e6e7e8e9eaebecedeeef 1111 F f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 下位 4 ビット 7 2 進数と 16 進数は相性が良い。 2 進数 4 桁が 16 進数 1 桁に対応するので直感的に分かり易い

ASCII 文字コード表 16 進 ABCDEF 0NULSOHSTXETXEOTENQACKBELBSHTLFVTFFCRSOSI 1DLEDC1DC2DC3DC4NAKSYNETBCANEMSUBESCFSGSRSUS 2SP!"#$%&'()*+,-./ :;<=>? 5PQRSTUVWXYZ[\]^_ 6`abcdefghijklmno 7pqrstuvwxyz{|}~DEL 8 9 A B C D E F 下位 4 ビット 赤字は制御コード 教科書 p.51., 第 2 週資料 p

標準ヘッダ // 文字コードの調査 (c が該当する文字なら真を返す ) int islower(int c); // 小文字 int isupper(int c); // 大文字 int isdigit(int c); //10 進数 ( 数字 ) int isxdigit(int c);//16 進数 int isalpha(int c); // 英字 (isupper(c)||islower(c)) int isalnum(int c); // 英数字 (isalpha(c)||isdigit(c)) int iscntrl(int c); // 制御文字 (0x00 ~ 0x1f, 0x7f) int isspace(int c); // 空白文字 (' ','\f','\n','\r','\t','\v') int isprint(int c); // 印字可能文字 (0x20 ~ 0x7e) int isgraph(int c); // 印字可能文字 ( スペースを除く ) isprint(c)&&!isspace(c) int ispunct(int c); // 印字可能文字 ( スペース、英数字を除 く )isgraph(c)&&!isalnum(c) // 文字コードの変換 int tolower(int c); //c を小文字に変換 int toupper(int c); //c を大文字に変換 9 [1] pp.303. JM: isalpha (3)isalpha touppertoupper (3) 講義資料の ctype_test.c, ctype_test.xlsx も参照

char 型変数と文字コード char, unsigned char 型 半角文字の文字コードを1つ つまり 1 バイト (=8 ビット ) を格納出来るサイ ズ char: -128 ~ 127 unsigned char: 0 ~ 教科書 pp.44, , 第 2 週資料 pp c 変数の実体は N バイト (8N ビット ) のメモリ つまり内部的には 2 進数が入っている 16 進数リテラルによる初期化 char c = 0x68; // =104='h' 文字コードに対応する文字を表示 printf("%c\n", 104); // "%c" に文字コードを与えると対応する文字が表示される

char 型変数と文字コード 以下の変数宣言と初期化は全く同じ結果 11 教科書 pp.44, , 第 2 週資料 pp c どの方法で初期化しようと結局 char 型 (1 バイト ) の変数 c を 0b で初期化している 文字コードを代入したい場合 文字定数リテラルで書くと 数値リテラルで書くよりも 意味が分かり易くなる 結果は同じでも読んだ時 分かり易いのはどれだろう? 必要であれば 読んだ人が分かり易いよう コメントで情報を補うと良い 文字定数リテラルによる初期化 char c = 'h'; // 0x68 10 進数リテラルによる初期化 char c = 104; // 'h' 16 進数リテラルによる初期化 char c = 0x68; // 'h' c 104 c 0x68 c 'h'

char 型配列と文字列 以下の変数宣言と初期化は全く同じ結果 12 文字定数リテラルによる初期化 char s[] = {'h', 'e', 'l', 'l', 'o', '\0'}; 文字列定数リテラルによる初期化 char s[] = "hello"; 教科書 pp.44, , 第 2 週資料 pp 進数リテラルによる初期化 char s[] = {104, 101, 108, 108, 111, 0}; 16 進数リテラルによる初期化 char s[] = {0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00}; s[0] 'h' s[1] 'e' s[2] 'l' s[3] 'l' s[4] 'o' s[5] '\0' 文字列は配列に格納した 一連の文字コード 終端には 0 を格納する どれで書いても良いが 普通は面倒だから 文字列の初期化は 文字列定数リテラルを 用いる

char 型配列と文字列 文字列の表示 13 文字列定数リテラルによる初期化 char s[] = "hello"; 教科書 pp.44, , 第 2 週資料 pp s[0] 'h' s[1] 'e' s[2] 'l' s[3] 'l' s[4] 'o' s[5] '\0' 文字列の表示 printf("%s\n", s); // "%s" に与えたアドレス以降 '\0' が現れるまで // メモリに格納された文字コードに対応する文字が表示される

関数の引数とよく使われる名前 p, ptr, pointer : ポインタ c, ch, chr, character : 文字 s, str, string : 文字列 s, src, source : 発信元 d, dst, destination : 送信先 t, txt, text : テキスト l, len, length : 長さ w, wid, width : 幅 h, hei, height : 高さ n, num, number : ( 個 ) 数 s, size : サイズ b, buf, buff, buffer : バッファ i, idx, index : 添え字 s, stat, status : 状態 14

標準ヘッダ 15

strlen 関数 size_t strlen(const char *s); 文字列 s の長さを返す 引数 : s: 長さを調べる文字列 戻り値 文字列 s の長さを返す 16 教科書 p.312., [1] pp JM: strlen (3)strlen

strcpy 関数 char *strcpy(char *dst, const char *src); '\0' を含めて src を dst へコピーする 引数 : dst: コピー先のアドレス src: コピー元の文字列 戻り値 dst を返す dst が十分な大きさでないとバッファオーバーフローを引き起 こすので注意 17 教科書 p.308., [1] pp JM: strcpy (3)strcpy

strncpy 関数 char *strncpy(char *dst, const char *src, size_t n); src から最大 n 文字 dst へコピーする 引数 : dst: コピー先のアドレス src: コピー元の文字列 n: コピーする最大文字数 戻り値 dst を返す src が n 文字より短い場合は、残りの dst の末尾に '\0' を詰めて、合計 n バイト書き込む 18 教科書 p.308., [1] pp JM: strcpy (3)strcpy

strcat 関数 char *strcat(char *dst, const char *src); 文字列 dst の末尾に文字列 src を連結する 引数 : dst: 連結先の文字列 src: 連結元の文字列 戻り値 dst を返す dst が十分な大きさでないとバッファオーバーフローを引き起 こすので注意 19 教科書 p.309., [1] pp JM: strcat (3)strcat

strncat 関数 char *strncat(char *dst, const char *src, size_t n); 文字列 dst の末尾に文字列 src を最大 n 文字連結する 引数 : dst: 連結先の文字列 src: 連結元の文字列 n: 連結する最大文字数 戻り値 dst を返す dst は strlen(dst)+min(strlen(stc),n)+1 の大きさがな ければバッファオーバーフローが発生する 20 教科書 p.309., [1] pp JM: strcat (3)strcat

strcmp 関数 char *strcmp(const char *s1, const char *s2); 文字列 s1 と s2 を比較する 引数 : s1: 比較する文字列 1 s2: 比較する文字列 2 戻り値 s1 が s2 に比べて小さければマイナスの値を返す s1 と s2 が等しければ 0 を返す s1 が s2 に比べて大きければプラスの値を返す 21 教科書 p.309., [1] pp JM: strcmp (3)strcmp

strncmp 関数 char *strncmp(const char *s1, const char *s2, size_t n); 文字列 s1 と s2 の先頭 n 文字を比較する 引数 : s1: 比較する文字列 1 s2: 比較する文字列 2 n: 比較する最大文字数 戻り値 strcmp に同じ 22 教科書 p.310., [1] pp JM: strcmp (3)strcmp

strchr 関数 char *strchr(const char *s, char c); 文字列 s のなかで最初に現れる c を見つける 引数 : s: 検索する文字列 c: 検索する文字 戻り値 最初に見つかった c へのポインタを返す 見つからなかった場合は NULL を返す 23 教科書 p.312., [1] pp JM: strchr (3)strchr

strrchr 関数 char *strrchr(const char *s, char c); 文字列 s のなかで最後に現れる c を見つける 引数 : s: 検索する文字列 c: 検索する文字 戻り値 最後に見つかった c へのポインタを返す 見つからなかった場合は NULL を返す 24 教科書 p.313., [1] pp JM: strchr (3)strchr

strspn 関数 int strspn(const char *s, const char *t); 文字列 s の先頭から、 t に含まれる文字だけからなる文字列の長 さを返す 引数 : s: 検索する文字列 t: 検索する文字の集合 戻り値 t に含まれる文字からなる接頭子 (prefix) の長さを返す 25 [1] pp JM: strspn (3)strspn

strcspn 関数 int strcspn(const char *s, const char *t); 文字列 s の先頭から、 t に含まれない文字だけからなる文字列の 長さを返す 引数 : s: 検索する文字列 t: 検索する文字の補集合 戻り値 t に含まれない文字からなる接頭子 (prefix) の長さを返す 26 [1] pp JM: strspn (3)strspn

strpbrk 関数 char *strpbrk(const char *s, const char *t); 文字列 s のなかで、 t に含まれる文字が最初に出てくる位置を見 つける 引数 : s: 検索する文字列 t: 検索する文字の集合 戻り値 t に含まれる文字が最初に見つかった位置へのポインタを返す 見つからなかった場合は NULL を返す 27 [1] pp JM: strpbrk (3)strpbrk

strstr 関数 char *strstr(const char *s, const char *t); 文字列 s のなかで、文字列 t が最初に現れる位置を見つける 引数 : s: 検索する文字列 t: 検索する文字列 戻り値 文字列 t が最初に見つかった位置へのポインタを返す 見つからなかった場合は NULL を返す 28 教科書 p.314., [1] pp JM: strstr (3)strstr

strtok 関数 char *strtok(char *s, const char *t); 文字列 s のなかから、 t に含まれる文字で区切られるトークンを 見つける 引数 : s: 検索する文字列 t: トークンを区切る文字の集合 戻り値 トークンへのポインタを返す 2 つ目以降のトークンは s を NULL にして呼ぶことで順次切り 出される トークンがなくなったらは NULL を返す s は区切り文字の位置が終端文字 '\0' で破壊される 29 [1] pp JM: strtok (3)strtok

memset 関数 void *memset(void *s, int c, size_t n); s の先頭から n バイトを c で埋め s を返す 引数 : s: データで埋める先頭アドレス c: メモリを埋める 1 バイトのデータ n: データ c を埋めるバイト数 戻り値 s を返す 要 string.h 30 [1] pp JM: memset (3)memset

memcpy 関数 void *memcpy(void *dst, const void *src, size_t n); dst に src の内容を n バイトコピーする dst と src は領域が重なっていてはならない。重なっている場合 は memmove を用いる 引数 : dst: データのコピー先 src: データのコピー元 n: コピーするバイト数 戻り値 dst を返す 要 string.h 31 [1] pp JM: memcpy (3)memcpy

memmove 関数 void *memmove(void *dst, const void *src, size_t n); dst と src は領域が重なっていても良い点を除けば、 memcpy と同 じ 引数 : dst: データのコピー先 src: データのコピー元 n: コピーするバイト数 戻り値 dst を返す 要 string.h 32 JM: memmove (3)memmove [1] pp

memcmp 関数 int memcmp(const void *s1, const void *s2, size_t n); s1 と s2 の最初の n バイトを比較する 引数 : s1: 比較するメモリ 1 s2: 比較するメモリ 2 n: 比較するバイト数 戻り値 strcmp に同じ 要 string.h 33 JM: memcmp (3)memcmp [1] pp

memchr 関数 void *memchr(const void *s, int c, size_t n); s の中で c が最初に現れる位置を見つける 引数 : s: 検索するメモリ c: 検索する値 n: 検索する範囲のバイト数 戻り値 c が最初に見つかった位置へのポインタを返す 見つからなかった場合は NULL を返す要 string.h 34 JM: memchr (3)memchr [1] pp

標準ヘッダ // 文字列を数値に変換 double atof(const char *s); // 文字列を double 型の数値に変換 int atoi(const char *s); // 文字列を int 型の数値に変換 long atol(const char *s); // 文字列を long 型の数値に変換 double strtod(const char *s, char **endp); long strtol(const char *s, char **endp, int base); unsigned long strtoul(const char *s, char **endp, int base); // 文字列を double, long, unsigned long 型の数値に変換する // endp が NULL でない場合、 // *endp は変換に用いた最後の文字の次の文字へのポインタとなる // base は変換元の文字列の基数 // base が 0 の場合、文字列先頭の 0 や 0x を解釈し // 8 進数や 16 進数として扱う 35 [1] pp JM: atof (3)atof atoiatoi (3) strtodstrtod (3) strtolstrtol (3)

シーザー暗号 文字列の演習 36

シーザー暗号 アルファベットを N 文字シフトする暗号 例 : IBM→1 文字左へ →HAL 37

演習 : caesar.c 与えられた文字列をシーザー暗号で暗号化する関数 caesar(n,s) を作成せ よ。 文字コードが 0x20 ~ 0x7e の文字ついてのみ処理し、それ以外の文字につい ては処理せずそのまま残すこと。 0x20 ~ 0x7e からはみ出す値は値域の反対側に繋がるよう循環するよう変換 せよ。例えば n=1 なら 0x61('a') は 0x62('b') に、 0x7e は 0x20 に変換され る変換される。 n=-1 の場合も同様で、 0x20 は 0x7e に変換される。 caesar_main.c と共にコンパイルして動作を確認せよ 引数 : int n : 暗号鍵 ( シフトする文字数 ) char s[] : 暗号化する文字列 ( 終端が '\0') 戻り値 なし (void) 与えた配列 s を上書きしてシーザー暗号で 暗号化した文字列で上書きせよ 38 mintty + bash + GNU C $ gcc caesar_main.c caesar.c &&./a n = 1 s = hal ibm

ヒント プロトタイプ宣言の末尾の ; を {} に変え れば関数の定義になる。 文字の末尾は \0 で終端されている。 i を増やしながら s[i] != '\0' の間ループを 続ければ良い。 s 全体を暗号文で上書きするには各 s[i] を暗号化して s[i] に戻してやれば良い。 39 caerar_main.c void caesar(int n, char s[]);4

ヒント 0x20 未満、 0x7e 超になった場合の処理は 幾つかやり方がある if 文等で場合分けする方法 剰余算を使う方法 等々 40

参考文献 [1] B.W. カーニハン /D.M. リッチー著 石田晴 久 訳、プログラミング言語 C 第 2 版 ANSI 規 格準拠、共立出版 (1989) 41