第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入

Slides:



Advertisements
Similar presentations
1 例題 ex3b ( 配列 ) 科学科プログラミング. 2 例題 : ex3b  以下の 3 つについて例題を進める ステップ 1 :配列 ステップ 2 :最小と最大 ステップ 3 :文字型の配列.
Advertisements

復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
情報処理演習C2 ファイル操作について (2).
ポインタ プログラミング入門2 第10回 芝浦工業大学情報工学科 青木 義満
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
第2章 数値の入力と変数 scanfと変数をやります.
ファーストイヤー・セミナーⅡ 第8回 データの入力.
データ構造とアルゴリズム 第10回 mallocとfree
基礎プログラミングおよび演習 第9回
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
C言語 第2講 生物機能制御学講座 濱田 農学部7号館209室.
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
第8回 プログラミングⅡ 第8回
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
構造体.
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
プログラミング応用 printfと変数.
プログラミング論 II 2008年10月30日 文字列
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
Cプログラミング演習 第7回 メモリ内でのデータの配置.
プログラミング演習I 2003年6月25日(第10回) 木村巌.
プログラミング序論 2. n人のインディアン.
第10章 これはかなり大変な事項!! ~ポインタ~
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング入門2 第11回 情報工学科 篠埜 功.
前回の練習問題.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
第7回 プログラミングⅡ 第7回
第11回 プログラミングⅡ 第11回
プログラミング基礎B 文字列の扱い.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
2013年度 プログラミングⅡ ~ 計算してみよう ~.
2015年度 プログラミングⅡ ~ 計算してみよう ~.
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
高度プログラミング演習 (09).
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
ネットワーク・プログラミング Cプログラミングの基礎.
第5回 プログラミングⅡ 第5回
高度プログラミング演習 (11).
標準入出力、変数、演算子、エスケープシーケンス
プログラミング論 文字列
プログラミング 4 文字列.
第3回簡単なデータの入出力.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第5回 配列 変数宣言、初期化について
printf・scanf・変数・四則演算
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
第2章 数値の入力と変数 scanfと変数をやります.
知能情報工学演習I 第9回(後半第3回) 課題の回答
プログラミング演習I 補講用課題
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入 13.4 キーボードからの文字列の入力 13.5 文字型配列と関数

13.1 文字と文字型変数 これまでに扱ったのは数値型変数 プログラミングでは文字も扱う場合が多い 整数型 13.1 文字と文字型変数 これまでに扱ったのは数値型変数 整数型   int : -2147483648 〜 2147483647  浮動小数点型  float : 10-38 〜 1038  double : 10-308 〜 10308 プログラミングでは文字も扱う場合が多い 文字型 char を用いる これらの他に、short int, long int, long double, また、unsigned がつくものなどがある。 詳細はプログラミング演習Ⅰの資料を参照 http://www.ced.is.utsunomiya-u.ac.jp/lecture/2009/prog/p1/kadai1/variable.html

文字型変数に文字を代入 プログラム例 13.1.1 より抜粋 1文字 = 1バイトの数値 int main(void) { char x; x = 'H'; printf("%c¥n", x); return 0; } 文字型変数 x を宣言 代入文でOK 1文字はシングル クォート(')でくくる 1文字用の書式指定子 p.180, 表A.3 ASCIIコード 1文字 = 1バイトの数値 8ビット(0~255)

文字型変数に文字を代入 プログラム例 13.1.1 の改変 #include <stdio.h> int main(void) { char x, y, z, u, v, w; x = 'H'; y = 'a'; z = 'p'; u = 'p'; v = 'y'; w = '!'; printf("%c%c%c%c%c%c¥n", x, y, z, u, v, w); printf("%d %d %d %d %d %d¥n", x, y, z, u, v, w); printf("%x %x %x %x %x %x¥n", x, y, z, u, v, w); return 0; } character decimal %c 文字 %d 10進数 %x 16進数 hexadecimal

文字列 William Shakespeare を配列変数 x に代入 13.2 文字列 複数個の文字(文字列、string という)は、 「char 型の配列」として扱う。 文字列はダブルクォート(")でくくること。 文字列の最終文字の次に、文字列の最後を示す \0 が入る。 null文字 プログラム例 13.2.2 より抜粋 文字列 William Shakespeare を配列変数 x に代入 int main(void) { char x[20] = {"William Shakespeare"}; printf("%s¥n", &x[0]); return 0; } 19字だが、 20字分用意 ここで、配列変数 x の先頭番地を指定すると、 x のすべてを表示する。 ただし最後の ¥O は表示しない 文字列用の書式指定子

文字列は配列に格納される W int main(void) i 1000 x[0] { l 1001 char x[]={"William Shakespeare"};  printf("%s¥n", x); return 0; } 1000 1001 1002 ・ x[0] x[1] x[2] x[3] x[4] &x[0] は 単に x でよい e \0 x[18] 文字列の終わり x[19] 正体は1バイトの数字の0

13.2 文字列 プログラム例 13.2.2 の改変 配列の長さ < 文字列の長さ の場合にどうなるか、試してみよう 13.2 文字列 配列の長さ < 文字列の長さ の場合にどうなるか、試してみよう プログラム例 13.2.2 の改変 #include <stdio.h> int main(void) { char x[??] = {"William Shakespeare"}; printf("%s¥n", x); return 0; } ここの値を変えて、配列の 長さを1つずつ減らしていく

文字列の正体 プログラム例 13.2.2 の改変 #include <stdio.h> int main(void) { int i; char x[20] = {"William Shakespeare"}; printf("%s¥n", x); for (i = 0; i < 20; i++) printf(" %d", x[i]); printf("\n"); return 0; } この出力結果を p.180、表A.3 のASCIIコード と比べてみよう

13.2 文字列 プログラム例 13.2.4 複数の文字列を扱う場合 → 2次元配列を使う #include <stdio.h> 13.2 文字列 複数の文字列を扱う場合 → 2次元配列を使う プログラム例 13.2.4 #include <stdio.h> int main(void) { char name[3][20] = {"William Shakespeare", "William Clinton", "William Henry"}; int i; for (i = 0; i < 3; i++) printf("%s¥n", name[i]); printf("\n"); return 0; } 前の数字が文字列の数 後の数字は「文字数+1」以上に

13.3 文字列の代入 配列(文字列)に代入文は使えない 文字列処理関数 (string.h を include) 13.3 文字列の代入 配列(文字列)に代入文は使えない 文字列処理関数 (string.h を include) strcpy(char *dst, char *src) string copy (ストリング・コピー)の略 引数の順序は代入文 dst ← src に対応 引数はポインタ(文字型配列の名前)

a ← "William Shakespeare" 13.3 文字列の代入 プログラム例 13.3.2 #include <stdio.h> #include <string.h> int main(void) { char a[31], b[31]; strcpy(a, "William Shakespeare"); printf("%s\n", a); strcpy(b, a); printf("%s¥n", b); return 0; } 入れ物は2つ用意 a ← "William Shakespeare" b ← a 文字列の代入 a William Shakespeare 実際にコピー b William Shakespeare

a ← "William Shakespeare" 13.3 文字列の代入(もどき) プログラム例 13.3.2 の改変 #include <stdio.h> int main(void) { char a[] = "William Shakespeare", *b; printf("%s\n", a); b = a; printf("%s¥n", b); return 0; } 入れ物は1つ a ← "William Shakespeare" 文字型ポインタを用意 b ← a アドレスデータの代入 データは共用 a William Shakespeare b

13.4 キーボードからの文字列の入力 プログラム例 13.4.2 #include <stdio.h> 13.4 キーボードからの文字列の入力 プログラム例 13.4.2 101 は文章を読み込むのに 十分と考えられる適当な数。 特別な意味はない #include <stdio.h> int main(void) { char sentence[101]; printf("文章を入力して下さい"); gets(sentence); puts(sentence); return 0; } キーボードから文字列を受け取り、 の配列変数 sentence に代入する ディスプレイに表示 gets は get string、puts は put string と覚えれば良い ゲットエス プットエス 参考: C言語の読み方サイト http://bubuzuke.s7.xrea.com/ISO10646/c_reading.html

失敗例 プログラム例 13.4.1 と 13.4.2 の混合 #include <stdio.h> int main(void) { char surname[51], sentence[101]; printf("姓を入力してください :"); scanf("%s", surname); printf("姓は %s です.\n", surname); printf("文章を入力してください "); gets(sentence); puts(sentence); return 0; } gets, getc, getchar があるときは scanf は使わない 製品開発には挙動不審な scanf は使われない

解決例 プログラム例 13.4.1 と 13.4.2 の混合 #include <stdio.h> int main(void) { char s[101], surname[51], sentence[101]; printf("姓を入力してください :"); gets(s); sscanf(s, "%s", surname); printf("姓は %s です.\n", surname); printf("文章を入力してください "); gets(sentence); puts(sentence); return 0; } gets + sscanf なら OK

13.5 文字型配列と関数 関数に文字列を渡す → ポインタ変数(配列名)を引数に プログラム例 13.5.2 2次元配列のまま渡す場合 13.5 文字型配列と関数 関数に文字列を渡す → ポインタ変数(配列名)を引数に プログラム例 13.5.2 2次元配列のまま渡す場合 #include <stdio.h> #define NSIZE 40 #define N_Mem 3 void input_name(int n, char name[][NSIZE]); void print_name(int n, char name[][NSIZE]); int main(void) { char f_and_g[N_Mem][NSIZE]; input_name(N_Mem, f_and_g); print_name(N_Mem, f_and_g); return 0; } 1行あたり40文字で3行分 の2次元配列を宣言 ポインタ(その配列 の先頭番地を指す) を引数とする 文字列を 読込む関数 文字列を 表示する関数

13.5 文字型配列と関数 プログラム例 13.5.2 (つづき) void input_name(int n, char name[][NSIZE]) { int i; for (i = 0; i < n; i++) { printf("苗字と名前を入力してください :"); gets(name[i]); } void print_name(int n, char name[][NSIZE]) for (i = 0; i < n; i++) printf("あなたの苗字と名前は %s です.\n", name[i]);

13.5 文字型配列と関数 プログラム例 13.5.3 ポインタ配列として渡す場合 #include <stdio.h> 13.5 文字型配列と関数 プログラム例 13.5.3 ポインタ配列として渡す場合 #include <stdio.h> #define NSIZE 40 #define N_Mem 3 void input_name(int n, char *name[]); void print_name(int n, char *name[]); int main(void) { int i; char f_and_g[N_Mem][NSIZE], *name[N_Mem]; for (i = 0; i < N_Mem; i++) name[i] = f_and_g[i]; input_name(N_Mem, name); print_name(N_Mem, name); return 0; } NSIZEが不要に 文字列ポインタ配列を用意 行ごとに2次元配列を 文字列ポインタ配列に すり替え

13.5 文字型配列と関数 プログラム例 13.5.3 (つづき) void input_name(int n, char *name[]) 13.5 文字型配列と関数 プログラム例 13.5.3 (つづき) void input_name(int n, char *name[]) { int i; for (i = 0; i < n; i++) { printf("苗字と名前を入力してください :"); gets(name[i]); } void print_name(int n, char *name[]) for (i = 0; i < n; i++) printf("あなたの苗字と名前は %s です.\n", name[i]); NSIZEが不要に

スキルアップタイム 1 以下の動作をするプログラムを作成してみよう。 ディスプレイに「文章を入力して下さい」と表示する。 キーボードから入力された適当な英語の文章   (例えば Boys be ambitious! など)を読み取る。 その文章をディスプレイに表示する。 これを3回繰り返す。   (1、2、3回目は各々違う文章を入力してみる) プログラム例 13.4.2 を参照

スキルアップタイム 1 のプログラムの流れ main printf で「文章を入力して下さい」 gets で文章を読み取り、変数に入れる スキルアップタイム 1 のプログラムの流れ ヘッダファイル、関数、記号定数の宣言部 main 変数宣言(必要な変数と そのデータ構造を決める) 3つの文章を記憶せず、読み込んで表示するだけなら1つの文章用1次元配列で OK 3回繰り返し printf で「文章を入力して下さい」 gets で文章を読み取り、変数に入れる puts で文章を表示 文字型配列sentence 終了

3個の文章を記憶する必要有り → 文字列の2次元配列が必要 スキルアップタイム 2 作ったプログラムを以下のように変更してみよう。 最初にディスプレイに「3つの文章を入力して下さい」 と表示する。 ディスプレイに「文章 i:」(iは1、2、3と変化する)と表示し、キーボードから入力される英語の文章を読み取る。これを3回繰り返す(この時点では表示はしない)。 3個の文章をまとめてディスプレイに表示する。 3個の文章を記憶する必要有り → 文字列の2次元配列が必要

スキルアップタイム 2 のプログラムの流れ (その1) スキルアップタイム 2 のプログラムの流れ (その1) ヘッダファイル、関数、記号定数の宣言部  main 変数宣言(必要な変数と そのデータ構造を決める) main で全ての作業を行う タイプ(この程度の課題ならこれでも十分) printf で「文章を入力して下さい」 繰返し gets で文章を読み取り、配列変数に入れる 繰返し puts or printf で配列変数に入った文章を表示 終 了

スキルアップタイム 2 の プログラムの流れ (その2) プログラム例 13.5.2 を参照 関数名、変数名は自分の好きなように決めてください これは一例 ヘッダファイル、関数、などの宣言部  文章を読み取る関数 input_sentence main printf で「文章を入力して下さい」 繰返し 変数宣言(必要な変数と そのデータ構造を決める) gets で文章を読み取る 文章を読み取る関数 文章を表示する関数 print_sentence 文章を表示する関数 繰返し printf or puts で文章を表示 終 了 文章用の2次元配列(その先頭へのポインタ)を引数としてデータをやりとりする

スキルアップタイム3 すべてできた人は、演習問題の問題13.3、問題13.5 をやってみよう。 問題13.3 用のデータを考えるのが面倒な人は下記のデータを使ってください。 学籍番号 氏名 科目Aの得点 1001 Akanishi Hideo 55 1005 Ishihara Satoshi 64 1013 Kitano Keiko 71 1024 Sakaguchi Erika 85 1030 Tanaka Kazuya 68