プログラミング論 ファイル処理 (中級編) http://www.ns.kogakuin.ac.jp/~ct13140/ProgC/

Slides:



Advertisements
Similar presentations
プログラミング演習 II 2005 年 1 月 19 日(第 9 回) 理学部数学科・木村巌. 前回までの復習 共用体( union type ) 共用体( union type ) 列挙 (enumerated type ) 列挙 (enumerated type ) 構造体、構造体のポインタ、
Advertisements

10: ファイル入出力 Linux にログインし、以下の講義ページ を開いておくこと teachers/w483692/CPR1/ C プログラミング入門 総機 1 ( 月 1) 1.
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
情報処理演習C2 ファイル操作について (2).
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
データ構造とアルゴリズム 第10回 mallocとfree
基礎プログラミングおよび演習 第9回
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
16.3 関数と構造体 構造体ポインタ 地底探査ゲーム
第13回 プログラミングⅡ 第13回
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
記憶クラス 変数をどのような記憶領域に割り当てるかを指定するのが記憶クラス 記憶クラスには、自動変数、静的変数、外部変数などがある。
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
情報処理Ⅱ 第13回 2006年1月20日(金).
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第11回 プロセス間通信4 仮想FTPの実現 担当:青木義満
前回の復習 ファイル入出力①.
情報処理Ⅱ 第13回 2004年01月25日(火).
10: ファイル入出力 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
第2回 Microsoft Visual Studio C++ を使ってみよう
プログラミング2 関数
Cプログラミング演習 第6回 ファイル処理と配列.
プログラミング 2 ファイル処理.
プログラミング論 ファイル入出力
Cプログラミング演習.
プログラミング応用 printfと変数.
プログラミング論 II 2008年10月30日 文字列
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
iioLoadFile()とiioMallocImageBuffer()の補足
Cプログラミング演習 第7回 メモリ内でのデータの配置.
iioLoadFile()とiioMallocImageBuffer()の補足
iioLoadFile()とiioMallocImageBuffer()の補足
プログラミング演習I 2003年6月25日(第10回) 木村巌.
画像処理プログラムの説明.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
プログラミング論 ファイル入出力
Cの実行モデル.
プログラミング入門 第12回 情報工学科 篠埜 功.
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
第4回 ファイル入出力方法.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
プログラミング演習I 2003年7月2日(第11回) 木村巌.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
プログラミング論 ポインタ
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
前回の復習.
情報処理Ⅱ 2007年1月26日(金).
ファイル操作について (1).
cp-3. 計算 (C プログラミング演習,Visual Studio 2019 対応)
プログラミング論 文字列
Cp-1. Microsoft Visual Studio 2019 C++ の使い方 (C プログラミング演習,Visual Studio 2019 対応) 金子邦彦.
C言語プログラミング・課題 ファイルを読み込んで、その内容を表示するプログラムを作成せよ。
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
コンピュータープログラミング (C言語)(10) 1.ファイル入出力
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
モバイルプログラミング第3回 Cプログラミングの基礎( 2 )
プログラミング演習I 補講用課題
第1章 文字の表示と計算 printfと演算子をやります 第1章 文字の表示と計算.
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

プログラミング論 ファイル処理 (中級編) http://www.ns.kogakuin.ac.jp/~ct13140/ProgC/

高水準と低水準のファイル処理 高水準ファイル処理 ファイルのデータを決められたブロック単位でメモリ(バッファ)に読み込み,バッファからデータ読み込む.バッファを読み切ったら次のデータをファイルからバッファに読む. バッファから処理するため,fscanfなど便利な機能がある. buffered I/Oとも言う. OS間で高い互換性がある. fopen, fread, fgetc, fscanfなど

高水準と低水準のファイル処理 低水準ファイル処理 関数とはしてはバッファせず,要求されたバイトを読み書きする. 実際は,関数とは別にOSがバッファする unbuffered I/Oとも言う. I/O(ファイル読み書き)に関するOS固有の機能を使用できる. 例: Linux固有のDirect I/O OS間で互換性が低い. open, read, lseekなど

高水準 fopen fopen("ファイル名", "モード"); 戻り値: 成功したらファイルへのポインタ, 失敗したら NULL. fopen_s(&fp, "ファイル名", "モード"); 戻り値: 成功したら0. 失敗したら0以外. モード: r, w, a, r+, w+, a+ r:読み込み, w:書き込み, a:追記 r+:読み書き, w+:読み書き, a+:追記読み書き モード: t, b t:テキスト, b:バイナリ

fopenのモード 例: "rt":read text "rb":read binary "r":read text(省略時はtext) "wt":write text "ab":append binary "r+b":read+ binary

fopenのモード モード 説明 ファイルがない場合 ファイルがある場合 "r" 読み込み read エラー(NULLを返す) 既存ファイルから読み込む "w" 書き込み Write 新規作成 既存の内容を破棄し,書き込む "a" 追記 append 既存の内容を保持し,その後ろに追記 "r+" 読み書き read+ 既存の内容を保持し,読み書き "w+" write+ 既存の内容を破棄し,読み書き "a+" 追記読み書き append+ 既存の内容を保持し,追記,読み書き

fopenのモード テキストモード バイナリモード 改行コードのOSごとの差を考慮してread, write read: 改行コード\r\n を \n に変換 Write: \n を 改行コード\r\n に変換 次スライド以降で詳解 バイナリモード 変換なく read, write

文字と文字コード 文字には,"文字コード"という数字が割り当てられている. 計算機はこの文字コード(通常ASCIIコード)を用いて文字を処理する. 文字 '0' '1' '2' '3' '4' 'A' 'B' 'C' 'a' 'b' 文字 コード 16進数 30 31 32 33 34 41 42 43 61 62 文字 コード 10進数 48 49 50 51 52 65 66 67 97 98

文字コード表示プログラム (1/2) void main(){ char ch; for(ch='A'; ch<='Z'; ch++){ printf("%c %d\n", ch, ch); } ヒント:'A'と65は同じ. ch='A' と ch=65 は同じ. ch<='Z' と ch<=90 は同じ 実行結果 A 65 B 66 C 67 D 68 : X 88 Y 89 Z 90

文字コード表示プログラム (2/2) void main(){ char ch; for(ch='a'; ch<='z'; ch++){ printf("%c %d\n", ch, ch); } ヒント:'a'と97は同じ. ch='a' と ch=97 は同じ. ch<='z' と ch<=122 は同じ 実行結果 a 97 b 98 c 99 d 100 : x 120 y 121 z 122

改行コード 「改行」に割り当てられている文字コード(改行コード)は,OSにより異なる. Windowsの場合 Linuxの場合 10進数の13, 10の2バイト. CR+LFの2バイト. (16進数で0D,0Aの2バイト) Linuxの場合 10進数の10の1バイト. LFの1バイト 旧Mac OSの場合 10進数の13の1バイト. CRの1バイト CR: carriage return, \r, 13(10), 0D(16), 復帰 LF: line feed, \n, 10(10), 0A(16), 改行

文字を読み込み,表示する プログラム(バイナリモード) #include <stdio.h> void main(){ FILE *fp; int ch; fp = fopen("S:\\a.txt","rb"); if( fp == NULL ){ (略) } while( (ch=fgetc(fp)) != -1 ){ printf("%d\n", ch); fclose(fp); "rb"の意味は後述

文字を読み込み,表示する プログラム(バイナリモード) #include <stdio.h> void main(){ FILE *fp; int ch, ret; ret = fopen_s( &fp, "s:\\a.txt", "rb"); if( ret != 0 ) { (略) } while( (ch=fgetc(fp)) != -1 ){ printf("%d\n", ch); fclose(fp); "rb"の意味は後述 Visual Studio版

文字を読み込み,表示する プログラム(実行結果) Windowで作った a.txtに対して 65 66 67 13 10 68 69 70 Linuxで作った a.txtに対して 65 66 67 10 68 69 70 a.txt ABC DEF すなわち,Windowsで作った 「ABC改行DEF」のファイルと, Linuxで作ったファイルでは, 内容が異なる

fopen テキストモードとバイナリモード fopen("S:a.txt", "rt"); fopen("S:a.txt", "wt"); 改行コードの変換を行う バイナリモード fopen("S:a.txt", "rb"); fopen("S:a.txt", "wb"); 改行コードの変換を行わない

文字を読み込み,表示する プログラム(テキストモード) #include <stdio.h> void main(){ FILE *fp; int ch, ret; ret = fopen_s( &fp, "s:\\a.txt", "rt"); if( ret != 0 ) { (略) } while( (ch=fgetc(fp)) != -1 ){ printf("%d\n", ch); fclose(fp);

文字を読み込み,表示する プログラム(実行結果) Windowで作ったa.txtに対して "rt" 65 66 67 10 68 69 70 "rb" 65 66 67 13 10 68 69 70 a.txt ABC DEF textモードでは, \r \n → \n 13 10 → 10 に変換されて読み込まれる.

文字を書き込むプログラム (テキストモード,Windows) #include "stdafx.h" #include <stdio.h> void main() { FILE *fp; int ch, ret; ret = fopen_s( &fp, "s:\\a.txt", "wt"); if (ret != 0 ) { (略) } fprintf( fp, "ABC\nDEF"); fclose(fp); Windowsにおける 実行結果 a.txt 65 66 67 13 10 68 69 70 textモードでは, \n → \r \n 10 → 13 10 に変換されて 書き込まれる.

文字を書き込むプログラム (バイナリモード) #include "stdafx.h" #include <stdio.h> void main() { FILE *fp; int ch, ret; ret = fopen_s( &fp, "s:\\a.txt", "wb"); if (ret != 0 ) { (略) } fprintf( fp, "ABC\nDEF"); fclose(fp); a.txt 65 66 67 10 68 69 70 binaryモードでは, \n → \r \n 10 → 13 10 の変換をしない.

文字を書き込むプログラム (テキストモード,Linux) #include <stdio.h> void main() { FILE *fp; int ch, ret; fp = fopen( "a.txt", "wt"); if( fp == NULL ){ (略) } fprintf( fp, "ABC\nDEF"); fclose(fp); Linuxにおける 実行結果 a.txt 65 66 67 10 68 69 70 Linuxでは, 改行コードは \n(10)なので, 変換なし.

高水準関数 fputc, fgetc fputc(char c, FILE *fp) fpのファイルにcの文字を書き込む 戻り値:正常時は出力文字コード,エラー時は-1 fgetc(FILE *fp) fpのファイルから1文字読み込む. 戻り値:正常時は取得文字コード,エラー時は-1 ヒント:EOFと-1は同一

高水準関数 fputs fputs(char *s, FILE *fp); fpのファイルに,文字列sを書き込む. void main() { FILE *fp; int ret; ret = fopen_s( &fp, "s:\\a.txt", "wt"); if( ret != 0 ){ (略) } fputs( "ABC\nDEF", fp); fclose(fp); }

高水準関数 fgets fgets(char *buf, int n, FILE *fp); fpのファイルから,bufに対して, n文字読み込む(n-1個の文字と,1個の終端記号) void main() { char buf[100]; FILE *fp; int ret; ret = fopen_s(&fp, "s:\\a.txt", "rt"); if( ret != 0 ){ (略) } fgets(buf, 100, fp); printf("%s\n", buf); fclose(fp); }

高水準関数 fprintf fprintf(FILE *fp, char s, ...); fpのファイルに,文字列sを書き込む. void main() { FILE *fp; int ret; ret = fopen_s(&fp, "s:\\a.txt", "wt"); if( ret != 0 ){ (略) } fprintf(fp, "ret=%d\n", ret); fclose(fp); }

高水準関数 fscanf fscanf(FILE *fp, char s, ...); fpのファイルから,文字列sに従い読み込む.  戻り値:正常時は代入された個数.エラー時は-1 void main() { FILE *fp; int ret, i; fp = fopen("s:\\a.txt", "rt"); if( fp == NULL ){ (略) } fscanf(fp, "%d", &i); fclose(fp); printf("i=%d\n", i); } S:\a.txt 23 456 実行結果 i=23

高水準関数 fscanf_s fscanf(FILE *fp, char s, ...); fpのファイルから,文字列sに従い読み込む.  戻り値:正常時は代入された個数.エラー時は-1 void main() { FILE *fp; int ret, i; ret = fopen_s(&fp,"s:\\a.txt","rt"); if( ret != 0 ){ (略) } fscanf_s(fp, "%d", &i); fclose(fp); printf("i=%d\n", i); } S:\a.txt 23 456 実行結果 i=23

高水準関数 fscanf S:\a.txt HP=23 MP=18 EXP=100 GOLD=99 実行結果 23 18 100 99 void main() { FILE *fp; int ret, hp, mp, exp, gold; fp = fopen( "S:\\a.txt", "rb"); if ( fp == NULL ){ (略) } fscanf(fp, "HP=%d\n", &hp); fscanf(fp, "MP=%d\n", &mp); fscanf(fp, "EXP=%d\n", &exp); fscanf(fp, "GOLD=%d\n", &gold); fclose(fp); printf("%d %d %d %d\n", hp, mp, exp, gold); }

高水準関数 fscanf_s S:\a.txt HP=23 MP=18 EXP=100 GOLD=99 実行結果 23 18 100 99 void main() { FILE *fp; int ret, hp, mp, exp, gold; ret = fopen_s(&fp, "s:\\a.txt", "rb"); if (ret != 0) { (略) } fscanf_s(fp, "HP=%d\n", &hp); fscanf_s(fp, "MP=%d\n", &mp); fscanf_s(fp, "EXP=%d\n", &exp); fscanf_s(fp, "GOLD=%d\n", &gold); fclose(fp); printf("%d %d %d %d\n", hp, mp, exp, gold); }

高水準関数 fscanf_s S:\a.txt HP=23 MP=18 EXP=100 GOLD=99 実行結果 ret=1 23 18 100 99 void main() { FILE *fp; int ret, hp=0, mp=0, exp=0, gold=0; ret = fopen_s(&fp, "s:\\a.txt", "rb"); if (ret != 0) { (略) } ret = fscanf_s(fp, "HP=%d\n", &hp); printf("ret=%d\n", ret); ret = fscanf_s(fp, "MP=%d\n", &mp); ret = fscanf_s(fp, "EXP=%d\n", &exp); ret = fscanf_s(fp, "GOLD=%d\n", &gold); fclose(fp); printf("%d %d %d %d\n", hp, mp, exp, gold); }

高水準関数 fscanf_s S:\a.txt HP=23 EXP=100 MP=18 GOLD=99 実行結果 ret=1 ret=0 23 0 100 0 void main() { FILE *fp; int ret, hp=0, mp=0, exp=0, gold=0; ret = fopen_s(&fp, "s:\\a.txt", "rb"); if (ret != 0) { (略) } ret = fscanf_s(fp, "HP=%d\n", &hp); printf("ret=%d\n", ret); ret = fscanf_s(fp, "MP=%d\n", &mp); ret = fscanf_s(fp, "EXP=%d\n", &exp); ret = fscanf_s(fp, "GOLD=%d\n", &gold); fclose(fp); printf("%d %d %d %d\n", hp, mp, exp, gold); }

高水準ブロックread,write fread(char *buf, int size, int n, FILE *fp); fpのファイルから,bufに,sizeバイト*n個分読み込む. 戻り値:読み込んだ個数.(バイト数でなく,0~nの個数) fwrite(char *buf, int size, int n, FILE *fp); bufから,fpのファイルに,sizeバイト*n個分書き込む. 戻り値:書き込んだ個数.(バイト数でなく,0~nの個数) fseek(FILE *fp, long n, int whence) fpのファイルのnの場所に移動. whenceがSEEK_SETなら,ファイルの先頭からnバイト目. SEEK_CURなら,現在の位置からnバイト目. SEEK_ENDなら,ファイルの終端からnバイト目.(nは0や負の数)

#include "stdafx. h" #include <stdio. h> void main() { FILE #include "stdafx.h" #include <stdio.h> void main() { FILE *fp; int ret; unsigned int width, height; unsigned char buf[8]; //8バイトの配列 ret = fopen_s(&fp, "s:\\a.png", "rb"); if (ret != 0) { (略) } fseek(fp, 16, SEEK_SET); //ファイルの16バイト目に移動 fread(buf, 4, 2, fp); //その場所から,4*2=8バイト読み込み fclose(fp); printf("%02x %0x2 %02x %02x\n", buf[0], buf[1], …); printf("%02x %0x2 %02x %02x\n", buf[4], buf[5], …); width = (buf[0]<<24U) + (buf[1] << 16U) + (buf[2] << 8U) + (buf[3]); height = (buf[4] << 24U) + (buf[5] << 16U) + (buf[6] << 8U) + (buf[7]); printf("%u * %u\n", width, height); } PNGファイルは, 16バイト目からの4バイトに 画像の横幅が, 20バイト目からの4バイトに 縦の長さが記録されている. <<はビットシフト