Microsoft PowerPoint - kougi8.ppt

Similar documents
Microsoft PowerPoint - kougi7.ppt

Microsoft PowerPoint - kougi6.ppt

Microsoft PowerPoint - kougi9.ppt

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - kougi11.ppt

Microsoft PowerPoint - kougi4.ppt

Microsoft PowerPoint - kougi2.ppt

Microsoft PowerPoint - handout09.ppt [互換モード]

ディジタル信号処理

情報処理演習 B8クラス

ディジタル信号処理

情報画像工学実験I-1

Microsoft PowerPoint - handout08.ppt

PowerPoint プレゼンテーション

Microsoft Word - Cプログラミング演習(10)

プログラミング基礎

Microsoft PowerPoint - kougi10.ppt

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

ファイル入出力

Taro-ファイル処理(公開版).jtd

C言語講座 ~ファイル入出力編~

Microsoft PowerPoint - guidance.ppt

Microsoft Word - Cプログラミング演習(9)

演算増幅器

Microsoft Word - no204.docx

ファイル入出力

PowerPoint プレゼンテーション

memo

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

PowerPoint Presentation

cp-7. 配列

2006年10月5日(木)実施

Prog1_12th

gengo1-12

02: 変数と標準入出力

ゲームエンジンの構成要素

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

gengo1-12

A/B (2018/10/19) Ver kurino/2018/soft/soft.html A/B

Microsoft Word - 3new.doc

02: 変数と標準入出力

PowerPoint プレゼンテーション

gengo1-12

Taro-ポインタ変数Ⅰ(公開版).j

slide4.pptx

計算機プログラミング

Microsoft PowerPoint - 14th.ppt [互換モード]

Microsoft PowerPoint - CproNt02.ppt [互換モード]

Microsoft PowerPoint - 第3回目.ppt [互換モード]

プログラミング演習3 - Cプログラミング -

Microsoft Word - Cプログラミング演習(12)

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft Word - no15.docx

Prog1_15th

Microsoft PowerPoint pptx

Prog1_10th

Microsoft PowerPoint - 13th.ppt [互換モード]

Microsoft PowerPoint - 13.ppt [互換モード]

V

PowerPoint Presentation

02: 変数と標準入出力

memo

02: 変数と標準入出力

Microsoft PowerPoint - prog04.ppt

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

プログラミング演習3 - Cプログラミング -

PowerPoint プレゼンテーション

FORTRAN( と C) によるプログラミング 5 ファイル入出力 ここではファイルからデータを読みこんだり ファイルにデータを書き出したりするプログラムを作成してみます はじめに テキスト形式で書かれたデータファイルに書かれているデータを読みこんで配列に代入し 標準出力に書き出すプログラムを作り

PowerPoint プレゼンテーション

Taro-リストⅠ(公開版).jtd

Microsoft PowerPoint - 12.ppt [互換モード]

PowerPoint プレゼンテーション

スライド タイトルなし

02: 変数と標準入出力

プログラミングI第10回

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

gengo1-2

※ ポイント ※

演習課題No12

格子点データの解析 1 月平均全球客観解析データの解析 客観解析データや衛星観測データのような格子点データは バイナリ形式のデータファイルに記録されていることが多いです バイナリ形式のデータファイルは テキスト形式の場合とは異なり 直接中身を見ることができません プログラムを書いてデータを読み出して

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

演算増幅器

JavaプログラミングⅠ

PowerPoint プレゼンテーション

02: 変数と標準入出力

Microsoft PowerPoint - adi05.ppt [互換モード]

program7app.ppt

Microsoft Word - Training10_プリプロセッサ.docx

PowerPoint プレゼンテーション

第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイ

Microsoft PowerPoint - prog06.ppt

Microsoft PowerPoint - handout07.ppt [互換モード]

新版明解C言語 実践編

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

memo

プログラミング基礎

Microsoft PowerPoint - prog08.ppt

memo

Microsoft Word - Cプログラミング演習(11)

Microsoft PowerPoint - CproNt11.ppt [互換モード]

Transcription:

C プログラミング演習 第 8 回構造体とレコードデータファイル 1

例題 1. バイナリファイル形式のファイル からのデータ読み込み 次のような名簿ファイル ( バイナリファイル形式 ) を読み込んで, 画面に表示するプログラムを作る name Ken Bill Mike age 20 32 35 address NewYork HongKong Paris 名簿ファイル 2

#include "stdafx.h" #include <math.h> struct Person { char name[20]; int age; char address[20]; ; int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; // データファイル読み込み fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; fclose( fp ); // 画面表示 for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; この fread はバイナリファイル形式のファイルを読み出す 3

ビルド後の画面 ビルドの手順 : ビルド のビルド ビルドが正常終了したことを示すメッセージ 1. 正常終了 を確認 4

実行中の画面 実行の手順 : デバッグ 実行 実行ウインドウが現れる 5

実行結果の例 6

例題 1 のプログラムが 行っていること データファイル ( バイナリファイル形式 ) fread で読み出し プログラムが使うメモリ空間 読み出しが終わったら実行ウインドウに表示 例題 1 では 3 人分のデータ fread は 3 回実行 7

1 つのファイル (132 バイト ) 構造体 Person の配列 a a[0] a[1] a[2] name age address name age address Ken 20 NewYork Ken 20 NewYork Bill 32 HongKong Bill 32 HongKong Mike 35 Paris Mike 35 Paris name, age, address の 3 つの メンバ から構成される 8

#include "stdafx.h" #include <math.h> struct Person { char name[20]; int age; char address[20]; ; int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; // データファイル読み込み fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; Person 構造体を, 1 度に1つ n = n + 1; fclose( fp ); // 画面表示 for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; この fread はバイナリファイル形式のファイルを読み出す 9

実際のメモリの中身 name age address 元々のファイルサイズ : 132バイト実メモリでのサイズ : 132バイト Ken Bill 20 32 NewYork HongKong バイナリファイル形式の性質 Mike 35 Paris 10

実際のメモリの中身 a[0] a[1] a[2] a[3] a[4] name age address 元々のファイルサイズ : 132バイト実メモリでのサイズ : 132バイト Ken Bill 20 32 NewYork HongKong バイナリファイル形式の性質 Mike 35 Paris 11

#include "stdafx.h" #include <math.h> struct Person { char name[20]; int age; char address[20]; ; int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; // データファイル読み込み fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; fclose( fp ); // 画面表示 for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; 構造体 Person の定義 ( 説明は後述 ) 12

#include "stdafx.h" #include <math.h> struct Person { char name[20]; int age; char address[20]; ; int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; // データファイル読み込み fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; fclose( fp ); // 画面表示 for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; 構造体 Person の定義 ( 説明は後述 ) 13

int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; ファイルオープンに失敗したときのみ実行される部分 // データファイル読み込み fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; ファイルオープンに失敗したら, fclose( fp ); // 画面表示プログラムが終わる for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; 14

while ( 1 ) は, 無条件に繰り返す int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char という意味になる file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; ( 1 が, 常に成り立つ条件式の意味 ) int i; int ch; // データファイル読み込み fp = fopen( file_name, "r" ); while による繰り返し部分 if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; fclose( fp ); // 画面表示 fread は, バイナリファイル形式での読み出し for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", この break; a[i].name, は,while a[i].age, による繰り返し処理 a[i].address ); から抜け出すという意味になる printf( "Enter キーを 1,2 回押してください.. プログラムを終了します n"); (if ch 文の条件が成り立ったときにのみ実行される = getchar(); ) return 0; 15

int _tmain(int argc, _TCHAR* argv[]) { 変数 max_lines の値は 100 const int max_lines = 100; const char file_name[] = z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; サイズ 100 の配列 int i; int ch; // データファイル読み込み fread の結果,1 倍とも読み出さ fp = fopen( file_name, "r" ); if ( fp == NULL ) { れなかった ( ファイルの終わりが fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; 来たなどの理由 ) n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; fclose( fp ); // 画面表示 for( i=0; i<n; は, i++ または の意味すでに, 100 回読み ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address 込みを終えた ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); ch = n の値は getchar();, 読み込ん return だ回数と等しくなる 0; 16

int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; // データファイル読み込み fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; for による繰り返し部分 fclose( fp ); // 画面表示 for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; 17

int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; // データファイル読み込み fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; n 回の繰り返し for による繰り返し部分 fclose( fp ); // 画面表示 for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; 18

配列とメモリアドレス 配列 a ( サイズは 100) 0 1 2 a[0] a[1] a[2] プログラムが使うメモリ空間メモリアドレス 0012ED80 0012EDAC 0012EDD8 構造体の配列 19

構造体 (struct) データの集合を一つのデータ型として扱う仕組み 新たな型名を付けて登録することができる 構造体の要素をメンバと呼び それぞれに型を指定し 名前を付ける 構造体のメンバとして他の構造体を含むことが許される 特に 同じ構造体をメンバとするもの ( 再帰的構造体 ) も許される 20

構造体の例 ( 非再帰的 ) name age address これで 1 つのデータ 例題 1 の構造体 21

演算子. の意味 構造体のメンバを指定 例題 1 では a[i].name a[i].age a[i].address 22

演算子 -> の意味 ポインタの指す構造体のメンバを指定 z->re_part = x; z が struct complex なる構造体を指すポインタ であるとして そのメンバ re_part に x の値を代入 23

例題 2. 構造体データのメモリ配置を見る 下記の構造体 ImaginaryNumber について, メモリアドレスを表示してみる 1 つの構造体は 16 バイト real_part 3.1 4.5-2.4 imaginary_part -2.4 5.1 6.3 8 バイト 8 バイト 24

#include "stdafx.h" #include <math.h> struct ImaginaryNumber { double real_part; double imaginary_part; ; int _tmain(int argc, _TCHAR* argv[]) { struct ImaginaryNumber a[] = {{3.1, -2.4, %3.1f は, 小数点以上は最大 3 桁, 小数点以下は最大 1 桁の表示 int i; int ch; for (i=0; i<3; i++ ) { a[0] に 3.1, -2.4 を a[1] に 4.5, 5.1 を a[2] に -2.4, 6.3 をセット {4.5, 5.1, {-2.4, 6.3; printf( " 複素数 %3.1f + %3.1f i n", a[i].real_part, a[i].imaginary_part ); for (i=0; i<3; i++ ) { printf( "address(a[%d]) = %p n", i, &(a[i]) ); & はメモリアドレスの取得 printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); %p はメモリアドレス return 0; の表示各自で行ってください ( 実行結果の確認まで ) 25

メモリアドレス表示 実行結果の例 表示されたメモリアドレス * メモリアドレスの値がここでの 例 と違っていることはある ( 動作は正しい ) 26

配列とメモリアドレス 配列 a ( サイズは 3) プログラムが使うメモリ空間メモリアドレス 0 1 2 a[0] a[1] a[2] 3.1-2.4 4.5 5.1-2.4 6.3 0012FEA8 0012FEB8 0012FEC8 構造体の配列 27

実際のメモリの中身 double 型の変数は 8 バイトになっている メモリアドレスの値がここでの 例 と違っていることはある 28

#include "stdafx.h" #include <math.h> struct ImaginaryNumber { double real_part; double imaginary_part; ; int _tmain(int argc, _TCHAR* argv[]) { 構造体 ImaginaryNumber の型宣言 struct ImaginaryNumber a[] = {{3.1, -2.4, {4.5, 5.1, {-2.4, 6.3; int i; int ch; for (i=0; i<3; i++ ) { printf( " 複素数 %3.1f + %3.1f i n", a[i].real_part, a[i].imaginary_part ); for (i=0; i<3; i++ ) { printf( "address(a[%d]) = %p n", i, &(a[i]) ); 構造体のメンバ 構造体の配列 a の宣言と初期化 printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; 29

構造体の型宣言 構造体には, 名前がある それぞれのデータ ( メンバという ) は, 名前と型 ( データの種類のこと ) がある. struct Person { char name[20]; int age; char address[20]; ; 名前 メンバ 30

参考. バイナリファイル形式の ファイル読み出し, 書き込み 最初にファイルの書き込みを行い, 次に, 書き込んだファイルの読み出しを行うプログラム 練習用の見本として示す 31

最初は書き込み データファイル ( バイナリファイル形式 ) fwrite で書き込み プログラムが使うメモリ空間 3 人分のデータを書き込む fwrite は 3 回実行 変数 orig 32

次は読み出し データファイル ( バイナリファイル形式 ) fread で読み出し プログラムが使うメモリ空間 変数 a 例題 1 では 3 人分のデータを書き込む 33

#include "stdafx.h" #include "stdafx.h" #include <math.h> struct Person { char name[20]; int age; char address[20]; ; int _tmain(int argc, _TCHAR* argv[]) { const int max_lines = 100; const char file_name[] = "z: PersonData.bin"; struct Person a[max_lines]; FILE *fp; int n; int i; int ch; struct Person orig[3] = { {"kaneko", 38, "hazozaki", {"ken", 20, "kaizuka", {"mike", 30, "tenjin" ; printf( " 書きます. ファイル名は %s n", file_name ); // データファイル書き込み fp = fopen( file_name, "w" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; // 書き出すのは 3 個 (i = 0, 1, 2) for ( i = 0; i < 3; i++ ) { fwrite( &(orig[i]), sizeof(struct Person), 1, fp ); fclose( fp ); printf( " 読みます. ファイル名は %s n", file_name ); // データファイル読み出し fp = fopen( file_name, "r" ); if ( fp == NULL ) { fprintf( stderr, " ファイル %s のオープンに失敗しました " ); return -1; n = 0; while( 1 ) { if ( ( fread( &(a[n]), sizeof(struct Person), 1, fp ) == 0 ) ( n >= max_lines ) ) { break; n = n + 1; fclose( fp ); // 画面表示 for( i=0; i<n; i++ ) { printf( "name: %s, age: %d, address: %s n", a[i].name, a[i].age, a[i].address ); printf( "Enter キーを 1,2 回押してください. プログラムを終了します n"); return 0; 最初は書き込み 次は読み出し 34

例題 3.Windows ビットマップファ イルの読み出し, 書き込み 24 ビットカラーの Windows ビットマップファイルについて, 簡単な計算を行ってみる 35

実行結果の例 z: Mandrill.bmp z: done.bmp 新しく生成されるファイル 36

画素の r, g, b 値 x > 0 に対して r'(x, y) = r(x,y) - r(x-1, y) g'(x, y) = g(x,y) - g(x-1, y) b'(x, y) = b(x,y) - b(x-1, y) x = 0 に対して r'(x, y) = 0 g'(x, y) = 0 b'(x, y) = 0 横方向の差分 ( 差分の量が大きいほど, 画素は 明るく なる ) 37

例題 3 のプログラムが 行っていること プログラムが使う Windows ビットマップメモリ空間ファイル ファイルヘッダヘッダ本体 fread を 3 回実行 38

例題 3 のプログラムが 行っていること プログラムが使う Windows ビットマップメモリ空間ファイル ファイルヘッダヘッダ本体 計算 39

例題 3 のプログラムが 行っていること プログラムが使う Windows ビットマップメモリ空間ファイル ファイルヘッダヘッダ本体 40

画像本体の実メモリ上での配置 24 ビットカラーの Windows ビットマップ 実メモリ上では, バイト列のデータ 41

画像本体の実メモリ上での配置 24 ビットカラーの Windows ビットマップ 実メモリ上では, バイト列のデータ 画素 (x,y) のデータは, 先頭から 3xy バイト目にある 42

画像本体の実メモリ上での配置 24 ビットカラーの Windows ビットマップ ファイルヘッダ typedef struct tagbitmapfileheader { unsigned short bftype; unsigned long bfsize; unsigned short bfreserved1; unsigned short bfreserved2; unsigned long bfoffbits; BITMAPFILEHEADER ヘッダ typedef struct tagbitmapinfoheader{ unsigned long bisize; long biwidth; long biheight; unsigned short biplanes; unsigned short bibitcount; unsigned long bicompression; unsigned long bisizeimage; long bixpixpermeter; long biypixpermeter; unsigned long biclrused; unsigned long biclrimporant; BITMAPINFOHEADER; 43