Download presentation
Presentation is loading. Please wait.
Published byひさとも かに Modified 約 8 年前
1
10: ファイル入出力 Linux にログインし、以下の講義ページ を開いておくこと http://www-it.sci.waseda.ac.jp/ teachers/w483692/CPR1/ 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 1
2
標準ライブラリ関数によりファイルの出力を 行う 画像ファイルの生成を例題として 配列の作成を復習する 関数を作ってプログラムを構造化する 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 2 今日の内容
3
文字コードの羅列でできているもの 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 3 テキストファイル Dear all, I hope you and your family are fine.... Dear all, I hope you and your family are fine.... Linux のコンソールで, od -ctx1 ファイル名 とすると、文字コードを表示できる。 Linux のコンソールで, od -ctx1 ファイル名 とすると、文字コードを表示できる。
4
Portable gray map image 他に、 PPM ( カラー ), PBM (2 値 ) がある 単純なフォーマット テキスト形式とバイナリ形式がある 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 4 PGM 画像ファイル P2 4 255 0 127 255 255 127 255 127 0 0 127 255 255 P2 4 255 0 127 255 255 127 255 127 0 0 127 255 255 PGM 画像ファイルの例 ( テキスト形式 ) PGM 画像 (4×4 pixel) header 画素値 横幅 高さ [pixels] フォーマットを識別する マジックナンバー 画素値の最大値 (= 白 )
5
1. テキストエディタで、前頁のテキストファイ ルを作り、 mini.pgm というファイル名で 保存する 2. ダブルクリックして画像ビューアで開く 4x4 ピクセルなので、拡大しないと見えない 手で作ると大変なので、プログラムで作りだ そうというのが、今日の本題です。 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 5 実演 : PGM 画像ファイルを手で作る
6
1. ファイルを開く プログラムから指定してた名前のファイルに読み 書きできるように準備すること 2. ファイルを読む・ファイルに書き込む I/O (input/output) と呼ばれる 通常は、ファイルの内容を順番にアクセスする ( シーケンシャルアクセス ; sequential access) ⇄ ランダムアクセス (random access) 3. ファイルを閉じる ファイルの処理を完了し、バッファに残っている ものを全て出力する 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 6 ファイル入出力の流れ
7
2015-06-15 C プログラミング入門 総機 1 ( 月 1) 7 例題 : PGM ファイルの出力 #include int main(void) { FILE *fp; fp = fopen("mini.pgm", "w"); fprintf(fp, "P2\n"); fprintf(fp, "4 4\n"); fprintf(fp, "255\n"); fprintf(fp, " 0 127 255 255\n");... fclose(fp);... 開いたファイルを識別するため情報を指すポインタ ファイルポインタと呼ばれる。変数名は何でもよい 開いたファイルを識別するため情報を指すポインタ ファイルポインタと呼ばれる。変数名は何でもよい ファイルを mini.pgm という名前で、 書きこみモードで開く fopen(), fprintf(), fclose() などは stdio.h で 宣言されている ファイル閉じる ファイルに文字列を書きこむ
8
fopen() にファイル名と モードを指定 FILE 型へのポインタが返 る ファイルを操作するために 必要な情報が入っている 変数に入れて使う 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 8 ファイルを開く #include FILE *fopen(const char *filename, const char *mode ); fopen() のプロトタイプ モー ド 意味 "r" 読み込み (read) 。ファ イルがなければエラーと なる。 "w" 書き込み (write) 。既存 のファイルは削除される "a" 追記 (append) 。既存の ファイルがあればその末 尾に追記され、なければ 新規作成される。 構造体(今後の講義で解説)であるが、 内容を理解する必要は通常ない 構造体(今後の講義で解説)であるが、 内容を理解する必要は通常ない
9
ファイルが開けない場合がある 読み込みモードで、ファイルが存在しない場合 書き込みモードで、書き込み禁止の場所の場合 etc... 失敗した場合 NULL ポインタが返る 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 9 ファイルオープンの失敗 { FILE *fp; fp = fopen("some.file", "w"); if(fp == NULL) { // エラー処理を行う
10
ファイルに書き込むための関数を利用 fprintf() は printf() と同じ使い方だが、第 1 引数にファイルポインタを与える 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 10 ファイルに文字列を書きだす #include int fprintf(FILE *stream, const char *format,...); fprintf() のプロトタイプ 関数内容 fwrite ポインタで指すメモリ領域を指定したサイズだけ読み取って、 ファイルに書き込む fputc (putc) 1 バイトだけファイルに書き込む fputs 文字列をファイルに書き込む fflush バッファの中身をすべて書きだす その他のファイル書き込み関数
11
ファイルポインタを引数に fclose() を呼ぶ ファイルの書き込みは、効率のためにバッ ファリングがされるが、 fclose() は自動的に fflush() を呼び出す 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 11 ファイルを閉じる #include int fclose(FILE *fp); fclose() のプロトタイプ
12
特定のパターンならループを使ってファイル を書きだせば書けそう 複雑な場合は? 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 12 大きい画像を作る { FILE *fp; int i; fp = fopen("grad.pgm", "w");... for(i = 0; i < 4; ++i) { fprintf(fp, "%d %d %d %d\n", i*50, i*50, i*50, i*50); } 画素値 0, 50, 100, 150 の グラデーション
13
配列の各要素を画素値だと思って、そこに絵 を書く ループを使ってファイルに書き出す 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 13 配列をキャンバスに使う 0025500 00 00 00000 002100 unsigned char image[32][32] 画素値の配列を作って、 絵を書く 画素値の配列を作って、 絵を書く
14
2015-06-15 C プログラミング入門 総機 1 ( 月 1) 14 コード例 { FILE *fp; int x, y; unsigned char image[32][32] = {{0}}; // image に絵を書く... // ファイル出力 fp = fopen("image.pgm", "w"); // エラーチェックをしてヘッダを書きだす... for(y = 0: y < 32; ++y) for(x = 0; x < 32; ++x) { fprintf(fp, "%d ", image[y][x]); } fclose(fp);... 32×32 ピクセルの配列をつ くり、ゼロで初期化する。 配列 image に画素値をい ろいろ入れる 空白でそれぞれの画素値が 区切られるようにする 行、列の順番で考えている
15
1 バイト (unsigned char) の配列をそのまま ファイルに書いた形式。ヘッダは P5 fwrite() を使って書きだす 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 15 PGM のバイナリ形式の場合 0025500 00 00 00000 002100 unsigned char image[32][32] #include size_t fwrite(const void *buf, size_t size, size_t count, FILE *fp); fwrite() のプロトタイプ buf の指す場所から、 size [bytes] * count [ 個 ] の領域の値を fp の指すファ イルに書き出す
16
配列に様々な絵を書きこむ関数を実現するに は、配列へのポインタとサイズを渡す 配列のサイズを関数は直接知ることができない 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 16 配列に絵を書く関数 // width x height の画像 img を color で塗りつぶす void fill(unsigned char *img, int width, int height, int color) { int x, y; for(y = 0; y < height; ++y) { for(x = 0; x < width; ++x) { // NG: img[y][x] = color; img[x + y*width] = color; } ポインタ引数で配列の先頭 位置を知っただけなので、 2次元配列としてアクセス できない。代わりに、座標 からメモリ上の位置を計算 する width x height の領域の先 頭へのポインタ
17
ファイル名などをプログラムで生成 自動的に日付を付ける 連番にする etc... printf() は標準出力 ( 画面 ) に文字列を出す fprintf() はファイルに文字列を出す 文字配列に出力するには、 sprintf() を使う 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 17 配列に文字列を書きこむ #include int sprintf(char *buffer, const char *format,...); sprintf() のプロトタイプ メモリ領域の先頭へのポインタ
18
sprintf() が書きだすのに十分大きい配列を 用意しておく はみ出してもエラーは出ない 他の使われている領域を破壊する可能性がある 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 18 sprintf() の使い方 char filename[10] '\0' { char filename[10] = ""; sprintf(filename, "img-%d.pgm", 5); 'i' 'm''g''-' '5''.' 'p''g''m' '\0' この例ではぎりぎりの文字 数となる。 5 の代わりに 10 としたら、はみ出してメ モリ破壊をしてしまう。 たとえば、ここが変数とな り、ループなどで変化する 実用上は 256 など、大きい 値を指定する
19
printf => 標準出力 ( 画面 ) fprintf => ファイル sprintf => メモリ ( 配列 ) ( 実は、 printf は stdout ファイルを指定した fprintf と同じ ) 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 19 まとめ
20
手順 fopen() のモードを "r" で開く fgetc(), fgets() で文字列を読み込み、メモリに書 きこむ fscanf() によって文字列を数値などに変換してメ モリに書きこむ その後、 sscanf() によって処理をしてもよい 読み込みの処理は、書きこむよりも難しいこ とが多い ファイルに「正しい」情報があるとは限らない 2015-06-15 C プログラミング入門 総機 1 ( 月 1) 20 テキストファイルの読み込み
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.