プログラミング入門2 第7回 文字列 数学関数 ファイルの入出力 芝浦工業大学情報工学科 青木 義満 I’ll get started with Introduction and Conventional works around our study, then mention our motivation and goal. Next, I’ll explain our 3D Face Modeling Method and its medical application. Finally, I’ll conclude this presentation with some future works. 芝浦工業大学情報工学科 青木 義満
今回の講義内容 文字列 数学関数の利用 ファイル入出力 文字列の配列の扱い 関数への受け渡し 平方根,べき乗,三角関数 など 平方根,べき乗,三角関数 など ファイル入出力 プログラミング入門2
文字列とは? (p.210) puts( “ぷろぐらみんぐ入門” ); “ABCD” 文字列リテラル 文字列リテラルとナル文字(NULL) 複数の文字の並び=文字列 文字列リテラルとナル文字(NULL) 文字列リテラルの末尾には,必ずナル文字が付加 puts( “ぷろぐらみんぐ入門” ); “”で囲まれた部分=文字列リテラル という “ABCD” A B C D 4文字 \0 1文字 + ‘\0’ → ナル文字 プログラミング入門2
char str[5]; 文字列型 “ABCD” ? 文字を格納するためのデータ型 文字の並び(文字列)を格納するには? A B C D 4文字 \0 1文字 + char str[5]; ? 要素数5の文字型の配列 プログラミング入門2
文字列を格納する配列 (p.210) ソースファイル名: list0902.c 文字列をchar型の配列に格納し,表示 #include <stdio.h> int main(void) { char str[4]; /* 文字列を格納する配列 */ str[0] = 'A'; /* 代入 */ str[1] = 'B'; /* 代入 */ str[2] = 'C'; /* 代入 */ str[3] = '\0'; /* 代入 */ printf("文字列strは%sです。\n", str); /* 表示 */ return (0); } プログラミング入門2
文字列の表示・初期化 printf( “文字列は%sです\n”, str ); 文字配列の初期化 前ページの例のように,一文字づつの代入は大変 以下の形式で,配列にまとめて文字を代入可能 配列の要素数は省略可能 変換指定 配列名を指定 printf( “文字列は%sです\n”, str ); char ss[ ] = { ‘A’, ‘B’, ‘C’, ‘D’, ‘\0’ }; char ss[ ] = “ABCD”; プログラミング入門2
文字列の初期化と表示 (p.211) ソースファイル名: list0903.c 文字配列を初期化し,printfで表示 #include <stdio.h> int main(void) { char str[ ] = "ABC"; /* 初期化 */ printf("文字列strは%sです。\n", str); /* 表示 */ return (0); } プログラミング入門2
scanf( “%s”, name ); 文字列の読込み char name[40]; scanf関数による文字列の読込み 名前を格納する文字配列を用意 scanfの使い方 char name[40]; 39文字までの文字を格納可 scanf( “%s”, name ); 文字列用変換指定 配列名 (文字配列の場合,&は不要!) プログラミング入門2
文字列の読込み (p.212) ソースファイル名: list0904.c 名前を表す文字列を読込み,挨拶をする #include <stdio.h> int main(void) { char name[40]; printf("お名前は:"); scanf("%s", name); printf("こんにちは、%sさん!!\n", name); return (0); } プログラミング入門2
文字列の配列 (p.214) 文字列に名前データを格納 複数の名前データの扱い char name[ ] = “aoki” ; 添え字変数を使っていないので, for文で回せない! char name2[ ] = “tokunaga” ; char name3[ ] = “okura” ; 同じ型のデータの集合 → 配列で実現 文字列を配列として扱えれば便利! プログラミング入門2
文字列の配列の実現 文字列のデータ構造 文字列の配列 1つの文字列自体が文字の集合 → 配列 1つの文字列自体が文字の集合 → 配列 複数の文字列を配列として扱うには?→ 2次元配列 name1 t o k u n a g \n i r name2 name3 char name1[ ] = “aoki” ; char name2[ ] = “tokunaga” ; char name3[ ] = “okura” ; o k u r a \n t n g name[0] name[1] name[2] i 0 1 2 3 4 5 6 7 8 name[3][9] 名前の数 (文字列データの個数) 名前の文字数(9文字分) プログラミング入門2
文字列の配列の実現 ソースファイル名: list0906.c (p.214) 複数の氏名データを文字列の配列で実現,表示 #include <stdio.h> int main(void) { char name[3][9] = { "aoki", "tokunaga", "okura" }; int i; printf("name[0] = %s\n", name[0]); printf("name[1] = %s\n", name[1]); printf("name[2] = %s\n", name[2]); for(i=0; i < 3; i++){ printf("name[%d] = %s\n", i, name[i]); } return(0); 文字列の配列の宣言と 初期化 文字列の配列の表示 プログラミング入門2
文字列配列への文字列の読込み ソースファイル名: list0907.c (p.215) キーボードから複数の氏名データを文字列配列に読み込み,表示 #include <stdio.h> int main(void) { char name[3][128]; int i; printf(“名前を入力\n"); for(i=0; i < 3; i++){ printf(“name[%d] :", i); scanf(“%s”, name[i]); } printf("名前を表示\n"); printf("name[%d] = %s\n", i, name[i]); return(0); 文字列の配列の宣言と 初期化(文字数を多めに確保) キーボードから文字列の配列へ データを読込み 注意:scanf関数は,文字列の場合,&はいらない! 文字列の配列の表示 プログラミング入門2
数学関数の必要性 数学関数 先週の課題 for文, +演算子 2乗の計算 (x-avg)*(x-avg) 平方b根? n乗,平方根,sin, cos… 数値計算用の便利な関数は? 数学関数 プログラミング入門2
C言語の数学関数 C言語標準の便利な数学関数群 sqrt(平方根),pow(n乗計算),sin, cos, tan(三角関数),その他 プログラミング入門2
-lm gcc xxx.c -o xxx 数学関数をプログラム中で使用するには? ソースファイルに数学関数定義の記述された “math.h”をインクルード コンパイル時に,以下の記述を追加 ソースファイル:xxx.c #include <stdio.h> #include <math.h> 数学関数用ヘッダー “math.h” をインクルードb Int main(void){ ・・・・・・・ gcc xxx.c -o xxx -lm -l → リンクオプション (使用する関数を指定) m → math.lib(数学関数)のm ソースファイル名 実行ファイル名 プログラミング入門2
代表的な数学関数たち(1) 平方根の計算 べき乗の計算 sqrt関数 仕様 double sqrt ( double x ); 役割 doubleの値を受け取り,その平方根を計算してdoubleの値で返す y = sqrt(4.0) y → 2.0 べき乗の計算 pow関数 仕様 double pow ( double x, double y ); 役割 xのy乗を計算し,その結果をdoubleの値で返す z = pow( 4.0, 2.0) z → 16.0 プログラミング入門2
数学関数の使用例(1) コンパイル方法 gcc math1.c -o math1 -lm ソースファイル名:math1.c 平方根,べき乗の計算 #include <stdio.h> #include <math.h> int main(void) { double x, y, z; printf("input x : "); scanf("%lf", &x ); y = sqrt(x); z = pow(x, 2.0); printf("入力値 = %f\n", x ); printf("平方根 = %f\n", y ); printf("2乗 = %f\n", z ); return(0); } math.hのインクルードを忘れずに! コンパイル方法 gcc math1.c -o math1 -lm プログラミング入門2
代表的な数学関数たち(2) 高校の復習 ラジアン 180°= 1π(ラジアン) 1°= π/180 (ラジアン) x°→ x*(π/180) 三角関数の計算 sin, cos, tan関数 仕様 double sin ( double x ); double cos ( double x ); double tan ( double x ); 役割 角度(単位ラジアン)を受け取り,sin, cos, tanを計算してdoubleの値で返す 高校の復習 ラジアン 180°= 1π(ラジアン) 1°= π/180 (ラジアン) 角度を°で入力し,ラジアンに変換 x°→ x*(π/180) プログラミング入門2
数学関数の使用例(2) コンパイル方法 gcc math2.c -o math2 -lm ソースファイル名:math2.c 三角関数 sin, cos, tan の計算 #include <stdio.h> #include <math.h> int main(void) { double x, sin_x, cos_x, tan_x; double radian; printf("input x : "); scanf("%lf", &x ); radian = x * (PI / 180.0); sin_x = sin(radian); cos_x = cos(radian); tan_x = tan(radian); printf("入力値 = %f\n", x ); printf("sin = %f\n", sin_x ); printf("cos = %f\n", cos_x ); printf("tan = %f\n", tan_x ); return(0); } math.hのインクルードを忘れずに! 角度を入力(単位は°) 角度の単位を°→ラジアンに変換 PI : πの値,math.h内でマクロ定義 #define PI 3.1415……… sin, cos, tanの計算 コンパイル方法 gcc math2.c -o math2 -lm プログラミング入門2
その他の数学関数の例 (他にもあります) pow(x, y) x の y 乗 sqrt(x) 平方 sin(x) サイン その他の数学関数の例 (他にもあります) pow(x, y) x の y 乗 sqrt(x) 平方 sin(x) サイン cos(x) コサイン tan(x) タンジェント asin(x) アーク・サイン acos(x) アーク・コサイン atan(x) アーク・タンジェント sinh(x) ハイパボリック・サイン cosh(x) ハイパボリック・コサイン tanh(x) ハイパボリック・タンジェント exp(x) e の x 乗 log(x) 自然対数 log10(x) 基底10の対数 abs(x) 絶対値(int用) fabs(x) 絶対値(double用) *三角関数の角度はラジアン プログラミング入門2
ファイルとは何か? ファイルの入出力 これまでのプログラム ファイルの必要性 プログラムが終了すると,計算結果などのデータは保存されない 変数の寿命は有限 ファイルの必要性 プログラム中のデータをファイルへ保存可能 ファイル内のデータをプログラム中に読み込み 間接的に他のプログラムとデータのやりとり ファイルの入出力 プログラミング入門2
ファイルとは? = ファイル 文章,画像,音楽データ → ファイルとして保存 ファイルの構造 パソコンでは,データは全てメモリ上に記録 文章,画像,音楽データ → ファイルとして保存 ファイルの構造 パソコンでは,データは全てメモリ上に記録 メモリ管理の単位: バイト(byte) ハードディスク,フロッピーディスク CD-ROM,メモリ-カード 等 バイト単位の データの連なり = ファイル プログラミング入門2
ファイルへのデータの書き込み ファイルにデータを書き込む際の手順 ファイルを開く データの書き込み ファイルを閉じる どのファイルに対して(ファイル名)? どのような形式で?(テキスト or バイナリ, Read or Write) データの書き込み 関数を使って,データをファイルに書き込む ファイルを閉じる 使ったファイルを必ず閉じる プログラミング入門2
ファイルを開く ~ fopen関数 FILE *fp FILE *fp; fp = fopen( “file.txt”, “w” ); データを書き込む先の ”ファイル名” を指定 どんなモードでファイルを開くか? 書き込み用 読込み用 読み書き用 ファイルを開く操作 FILE *fp (ファイルポインタ) file.txt (ファイル) FILE *fp; fp = fopen( “file.txt”, “w” ); ファイルを指定 ファイルを開く 際のモード ファイル名 fp を介して,ファイルにアクセスが可能! プログラミング入門2
ファイルを開く際のモードの種類 (テキストファイル) ファイルを開く際のモードの種類 (テキストファイル) モード 意味 “r” 読込み用にファイルを開く。ファイルが存在しない場合や見つからない場合は失敗する。 “w” 書き込み用にファイルを作成。ファイルが存在する場合はそのファイルの内容は破棄する。 “a” 追加書き込みのために既存ファイルを開く。ファイルが存在しない場合には作成する。 “r+” 読み書き用にファイルを開く。ファイルは存在していなければならない。 “w+” 読み書き用にファイルを作成。ファイルが存在する場合には,そのファイルの内容は破棄する。 “a+” 読込みと追加の両方のモードでファイルを開く。ファイルが存在しない場合は作成する。 プログラミング入門2
ファイルへのデータの書き込み ~ fprintf関数 → fprintf関数(fileへのデータ出力) fprintf関数の書式 printf関数 printf( “iの値は%dです\n”, i ); fprintf関数 iの値は1です file.txt fprintf( fp, “iの値は%dです\n”, i ); データ書き込み先 」のファイル(ポインタ) プログラミング入門2
fprintf関数の使用例 double x → fprintf( fp, “%f\n”, x ); 実数データの書き込み 文字列データの書き込み 複数の型のデータを1行に書き込み double x → fprintf( fp, “%f\n”, x ); char str[256] → fprintf( fp, “%s\n”, str ); char name[ ] = “morishima”; int student_id = 100; double tensu = 95.5; 名前 学籍番号 点数 → fprintf( fp, “%d %s %f \n”, student_id, name, tensu ); プログラミング入門2
ファイルを閉じる 使い終わったら,後片付け ファイルを閉じる ファイルを開く時に指定したファイルポインタを指定 fclose(fp); プログラミング入門2
ファイルへのデータ書き込み 例題 ソースファイル名:fileio1.c 様々なデータをファイルに書き込み ファイルポインタ宣言 ファイルへのデータ書き込み 例題 ソースファイル名:fileio1.c 様々なデータをファイルに書き込み #include <stdio.h> int main(void) { FILE *fp; int student_id = 100; char name[ ]= "morishima"; double tensu = 95.5; fp = fopen("test.txt","w"); fprintf( fp, "%d\n", student_id ); fprintf( fp, "%s\n", name ); fprintf( fp, "%f\n", tensu ); fprintf( fp, "%d %s %f\n", student_id, name, tensu ); fprintf( fp, "%d\t%s\t%f\n", student_id, name, tensu ); fclose(fp); return(0); } ファイルポインタ宣言 ファイルに書き込むデータ “test.txt”という名前でファイルをオープン (書き込み用) データをファイルに書き込み ファイルを閉じる プログラミング入門2
演習課題 1 )名前の入力とファイルへの書き込み(kada7-1.c) 2)数学関数を用いた数値計算(kadai7-2.c) キーボードから数人分の氏名を入力し,入力した氏名データを画面表示した上で,以下のようにテキストファイルに保存せよ。 2)数学関数を用いた数値計算(kadai7-2.c) 2つのベクトルの成分P1 (x1, y1), P2 (x2, y2) をキーボードから入力し,内積の値を利用して,2つのベクトルの成す角度θ(°)を求めよ。 name.txt fprintf scanf char name[NUM][128]; Aoki Tokunaga Okura Morishima Komiya ・・・・・・ cos-1 : アークコサイン → acos関数使用 参考: o P1 (x1, y1) θ θはラジアンで出るので, 角度(°)に変換して表示 プログラミング入門2
演習課題 3) 数学関数を用いた数値計算(kadai7-3.c) 以下の2次方程式の係数(a, b, c)を入力し,その方程式の解が ① 実数解(2つ) ② 実数解(1つ(重解)) ③ 虚数解 のどの解を持つかを判別せよ。 また,実数解を持つ(①,②)場合には,その解を求めて表示せよ。 解の判別 X=? プログラミング入門2
課題提出方法 メールにてソースファイル(kadai7-1.c 〜 kadai7-3.c)を添付し, 提出 日時:11月26日(月)13時まで 提出先:yaoki@sic.shibaura-it.ac.jp メールのタイトル:pro2-7 学籍番号 苗字(全て半角英数) 例) pro2-7 L02001 aoki プログラミング入門2