プログラミング言語 2 第 04 回 (2007 年 05 月 14 日 ) 今日の配布物 片面の用紙 1 枚 今日の課題が書かれています 本日の出欠を兼ねています 1
今日やること http://www.tnlab.ice.uec.ac.jp/~s-okubo/class/language/ にアクセスすると 教材があります 2007 年 05 月 14 日分と書いてある部分が 本日の教材です 本日の内容 先週の課題の簡単な解答 ファイルからのからの入力 ファイルへのへの出力 XGraph を使ったったグラフグラフの書き方 第 3 回の課題の簡単な解説 2
第 3 回の課題の簡単な解説 問題 1: 次の printf が何を出力するか答えなさい printf("%s n",str): 文字型の配列 str の内容を文字列として出力し 改行する %s は 引数をポインタ ( アドレス ) として扱い そのアドレスから順番に NULL になるまで 文字を表示します 文字型の配列 str に対して str とだけ書くとアドレスになることを思い出しましょう 第 3 回の課題の簡単な解説 問題 1: 次の printf が何を出力するか答えなさい printf("%u n",str): 文字型の配列 str のアドレスを 符号なし 10 進数として出力し 改行する 配列の [] が無い部分は その配列のアドレスとなります 一番最初の要素のアドレスを同じものになります 3
第 3 回の課題の簡単な解説 問題 1: 次の printf が何を出力するか答えなさい printf("%c n",str[3]): 文字型の配列 str の 4 番目の要素を 文字型として出力し 改行する 文字型の配列の個々の要素は文字型です printf("%u n",&str[0]): 文字型の配列 str の最初の要素を 符号なし 10 進数として出力し 改行する printf( %u n,str): と同じ結果になります 第 3 回の課題の簡単な解説 問題 1: 次のprintfが何を出力するか答えなさい printf("%d n",*&i): 整数型 i の値を 符号つき10 進数として出力し 改行する 右側から考えるとわかりやすいです i : 整数値の変数 ( の値 ) &i : 整数値の変数に & がついているので その値を保存しているアドレス *&I : アドレス (&i) に * がついているので そのアドレスに保存されている変数 ( の値 ) 4
第 3 回の課題の簡単な解説 問題 2: 次の要求を満たすプログラムを書いて提出しなさい 要求 1:1~3までの値のうち いずれかをキーボードから printf("%d n",*&i): 入力したとき 1が入力されたときはMonday と出力し 改行する 2が入力されたときは Tuesday と出力し 改行する 3が入力されたときはWednesday と出力し 改行する 要求 2:1~3 以外の値が入力されたときのことは 考えなくてもよい ポイント : 1. scanf で値を読み込むことができるか? 2. 条件分岐が ちゃんとできるか? 第 3 回の課題の簡単な解説 問題 2: 前半部 #include<stdio.h> // // 入出力を使うので stdio.h を include する main(){ int inti; i; // // 整数型の変数 iを宣言する i scanf("%d",&i); // // 標準入力から読み込み // // i i に符号付き 10 10 進数を代入 代入する先はアドレスで与える 5
第 3 回の課題の簡単な解説 問題 2: 後半部 : if 文を用いた場合 if(i==1){ // // もし iの内容が i 1 であったなら printf("monday n"); // // Monday を出力して改行する }else if(i==2){ // // もし iの内容が i 1 でなく 2 であったなら printf("tuesday n"); // // Tuesday を出力して改行する }else if(i==3){ // // もし iの内容が i 1 や 2 でなく 3 であったあなら printf("wednesday n"); } } switch 文の説明 switch( 整数式 ){ } case ラベル 1: 文 1 case ラベル 2 : 文 2 default: 文 3 整数式を評価し 対応するラベルまでジャンプします 対応するラベルが無い場合 default にジャンプします ラベルの数は任意です default は省略可能です 途中で抜けるときは berak を用います 6
switch 文の説明 #include<stdio.h> int t; scanf("%d",&t); switch(t){ } case 1: 文 1 case 2: 文 2; break; case 3: 文 3 default: 文 3 対応するラベルまでジャンプ 対応するラベルがないと default にジャンプ break で switch 文の外に t=1 のとき t=2 のとき t=3 のとき t=4 のとき 第 3 回の課題の簡単な解説 問題 2: 後半部 : switch 文を用いた場合 } } switch(i){ case 1: 1: printf( Monday n ); // // i i が 1 なら ここに飛ぶ break; // // switch 文の外まででる case 2: 2: printf( Tuesday n ); // // i i が 2 なら ここに飛ぶ break; // // switch 文の外まででる case 3: 3: printf( Wednesday n ); break; // // switch 文の外まででる 7
ファイルの入出力 ファイルへの入出力 C 言語では ファイルへの出力や ファイルからの入力を行うことができる ファイルの入力と出力を行う printf 系の命令 (fprintf, fscanf) が準備されている 標準入力や標準出力への入出力とは異なる点も 対象とするファイルの指定して開く (fopen) 処理の終わったファイルを閉じる (fclose) 8
プログラムの流れ 1. ファイル構造体へのポインタを宣言する 2. ファイルを開く (fopen) 3. ファイルへ書き込んだり (fprintf) ファイルから読み込んだり (fscanf) する 4. ファイルを閉じる (fclose) ( 構造体とは何かについては そのうちやります ) ファイル構造体 1. ファイル構造体構造体へのへのポインタポインタを宣言宣言するする 2. ファイルを開く (fopen) 3. ファイルへ書き込んだり (fprintf) ファイルから読み込んだり (fscanf) する 4. ファイルを閉じる (fclose) 最初に ファイル構造体へのポインタを宣言する必要がある fprintf や fscanf は ファイル構造体へのポインタを通じて 書き込み先の指定等を行う 以下のように宣言する FILE *fp; ( もちろん fp 以外の名前でも良いです ) 9
プログラムの流れ ファイル構造体へのポインタを使って 対象となるファイルを指定 1. ファイル構造体へのポインタを宣言する 例えば FILE *fp; と宣言 2. ファイルを開く (fopen) ファイルを開いて fp と関連づける 3. ファイルへ書き込んだり (fprintf) ファイルから読み込んだり (fscanf) する fp に対して 書き込みや読み込みを行う 4. ファイルを閉じる (fclose) fp とファイル名の関連づけを消して ファイルを閉じます ファイルのオープン fopen は 指定したファイルを開き FILE 構造体へのポインタを返す 書式は fopen(name,action); のようになる ここで name と action は文字列である 1. ファイル構造体へのポインタを宣言する 2. ファイルを開く (fopen) 3. ファイルへ書き込んだり (fprintf) ファイルから読み込んだり (fscanf) する 4. ファイルを閉じる (fclose) nameは ファイル名をいれる actionは 以下のうちの何れかをいれる 書き込みのみ(w) 読み込みのみ(r) ファイルの末尾に書き込み(a) 読み書き兼用(w+ or r+) 読み込みとファイルの末尾に書き込み兼用(a+) 10
ファイルのクローズ fclose は 指定したファイルを閉じる 書式は fclose(fp); のようになる ここで fp はファイル構造体へのポインタ 1. ファイル構造体へのポインタを宣言する 2. ファイルを開く (fopen) 3. ファイルへ書き込んだり (fprintf) ファイルから読み込んだり (fscanf) する 4. ファイルを閉じる (fclose) 例 : 1. ファイル構造体へのポインタを宣言する 2. ファイルを開く (fopen) 3. ファイルへ書き込んだり (fprintf) ファイルから読み込んだり (fscanf) する 4. ファイルを閉じる (fclose) #include<stdio.h> // // 入出力を使うので stdio.h stdio.hを include include FILE *fp; // // ファイル構造体へのポインタ fp fp を宣言 main(){ } ファイル example.txt を書き込み専用で開いて その後 閉じるには fp=fopen("example.txt","w"); fclose(fp); // // ファイルをクローズする example.txt を読み込み専用で 開いて fp にポインタを返す 11
関数 fscanf は データをフォーマットに従って ファイルに出力します 書式は 書き込み 1. ファイル構造体へのポインタを宣言する 2. ファイルを開く (fopen) 3. ファイルへ書き込んだり (fprintf) ファイルから読み込んだり (fscanf) する 4. ファイルを閉じる (fclose) fscanf(fp, format [,pointer]); のようになる format として scanf と同様のモノが指定できる 関数 fscanf は データをフォーマットに従って ファイルに出力します 書式は 読み込み 1. ファイル構造体へのポインタを宣言する 2. ファイルを開く (fopen) 3. ファイルへ書き込んだり (fprintf) ファイルからから読み込んだり (fscanf) する 4. ファイルを閉じる (fclose) fprintf(fp, format [,arg]...); のようになる format として printf と同様のモノが指定できる 12
読み書き例 #include<stdio.h> // // 入出力を使うので stdio.h stdio.hを include include FILE *fp; // // ファイル構造体へのポインタ fp fpと fp2 fp2を宣言 int i; i; // // 整数型の変数 i を宣言 main(){ fp=fopen("input.txt","r"); // // 読み込みのみで開く fp2=fopen("output.txt","w");// 書き込みのみで開く fscanf(fp,"%d",&i); fprintf(fp2,"%d",i); fclose(fp); // // ファイルをクローズする fclose(fp2); // // ファイルをクローズする } // // 符合付き 10 10 進数を読み込む // // 符合付き 10 10 進数を書き込む printf の format printf(format [,arg]...); format に従って出力を行う format の部分は 文字列である % から始まるものは 順番に arg を参照して変換される それ以外 ( たんなる文字とか ) は そのまま 例 : int i; char c; char str*; printf("print %d %c %s n",i,c,str); そのまま出る 空白や改行も そのままでる 符合無し 10 進数に置換される 文字列に置換される 文字に置換される 13
XGraph によるグラフの書き方 Xgraph とは 2 次元のグラフを書くプログラム 所定の形式のデータを読み込ませることによって 簡単にグラフを書くことができる 読み込ませるデータはテキストファイル グラフを Postscript 形式で保存することもできる 14
入力データ形式 普通のテキストファイル 1 行に 2 つの値を書く (x 座標と y 座標を書く ) 2 つの値はスペースで区切る 例 : x 座標の値 0 0 1 1 2 4 3 9 4 16 5 25 y 座標の値スペースで区切る 入力データ形式 複数のグラフを書くときは データを空行で分割する 例は整数だけど 実数でも大丈夫 1 つめのグラフ 空行で区切る 2 つめのグラフ 0 0 1 1 2 4 3 9 4 16 5 25 0 0 1 1 2 2 3 3 4 4 5 5 15
Xgraph の使い方 コンソールで xgraph 入力データファイル名 とうつと グラフが出てくる データファイルが xgraph00.dat なら xgraph xgraph00.dat Postscript ファイルでの保存 Hardcopy をクリック 16