cp-14. ファイル処理
C プログラミング入門)
URL: https://www.kkaneko.jp/pro/adp/index.html
1
金子邦彦
アウトライン
例題1. 1行単位のファイル読み込み
ファイルからの読み込み
ファイルの終わり(EOF ともいう)
例題2.ファイルからのデータ読み込み
ファイル中のデータの取り出し
例題3. 1行単位のファイル書き出し
ファイルへの書き出し
例題4. 3行目を2回読み込む
ファイルのランダムアクセス
2
ファイル読み込み
ファイル
プログラム
ファイルの中身は書き換わらな
3
ファイル書き出し
ファイル
プログラム
ファイルの中身が書き換わる
ファイルは伸び縮みすることが
ある 4
目標
ファイルの読み書きを行うような、簡単なプロ
ラムを書けるようになる
ファイルを扱う手順(オープン,読み込み,書
き出し,クローズ)を理解する
5
例題1.1行単位のファイル読み込み
ファイルを読み込んで,ファイルの中身に行
番号を付けて表示するプログラムを作る.
ファイルの読み込みでは,1行単位の読み込みを
行うために fgets 関数を使う
ファイルのオープンを行うために fopen 関数を使
い,ファイルのクローズを行うために fclose 関数
を使う
6
#include <stdio.h>
#pragma warning(disable:4996)
int main()
{
char line[100];
int i = 1;
FILE *in_file;
in_file = fopen("d:\\input.txt", "r");
if ( in_file == NULL ) {
printf( "fopen() error" );
return 0;
}
while( fgets( line, 100, in_file ) != NULL ) {
printf( "[%d]%s", i, line );
i++;
}
fclose(in_file);
return 0;
}
ファイルポインタ変数の宣言
ファイルのオープン
(ファイルポインタが得
られる)
ファイルのクローズ
(ファイルポインタを使ってクローズする)
ファイルのオープンに
失敗したかを調べている
ファイルの終わりに達し
ていないかを調べている
ファイルの
1行読み込み
7
実行結果例
[1]アレンジメントの特質
[2]・空間を分割
[3]・分割された部分(フェイス)は,凸性を有する(従って
有界)か,
[4] 非有界な半空間
[5]・ボロノイ図を容易に導ける
[6]・単体に容易に分解できる
8
プログラムとデータ
メモリ
fgets( line, 100, in_file )
ファイルの
1行読み込み
line[0]
line[1]
line[2]
line[3]
line[4]
printf( "[%d]%s", i, line );
1行分の表示
9
プログラム実行順
in_file = fopen("d:\\input.txt", "r");
fgets( line, 100, in_file ) != NULL Yes
No
fclose(in_file);
printf( "[%d]%s", i, line );
i++;
10
ファイルのオープンとクローズ
ファイルのオープン
ファイルの読み書きを行う前に、ファイルはオー
プンされねばらならい
ファイルのクローズ
ファイルの読み書きが終わったら,ファイルはク
ローズされねばならない
11
ファイルポインタ
ファイルポインタ変数の宣言
例)FILE *in_file;
in_file」という名前の付いたファイルポインタ変数を宣
ファイルのオープン
例)in_file = fopen("d:\\input.txt", "r");
ファイルのオープンを行うと,ファイルポインタが得られる
ファイルのクローズ
fclose(in_file);
ファイルポインタを使って,ファイルのクローズを行う
オープンすべき
ファイル名
オープンモード
r 読み込みの意味
w: 書き出しの意味
12
ファイルポインタ変数の働き
・現在のファイルのファイル位置指示子
(ファイルの読み書き位置)
・ファイルのオープンモード
など
13
fgets の意味
ファイルの1行読み込み
ファイルの一行分を読み込んで,末端の\0を付ける
ファイルには,行の終わりに,改行記号(\n)が付い
ている(目には見えない)
読み込み先(文字の配列)のサイズが,ファイルの1
行の長さより長いときは,「残りの部分」は変化しな
文字の配列
ファイル
M a r k \n \0
改行記号 文字列の末端
変化しない部分
Mark\n
14
fgets で「100」を書く理由
文字の配列
ファイル
\0
文字列の末端
fgets( line, 100, in_file )
配列のサイズが100ならば,読み込める文字は99まで
(最後に必ず「\0」が付く)
ファイルポインタ
変数名
読み込み先の
配列のサイズ
読み込み先の
配列の変数名
15
NULLの意味
fopen 関数では「ファイルオープンの失敗」
例) fopen(“d:\\input.txt", "r")
if ( in_file == NULL ) {
fgets 関数では「ファイルの終わり」
例) fgets( line, 100, in_file ) != NULL
16
次のような名簿ファイルを読み込んで,1列目
の氏名と,3列目の住所だけを表示するプログ
ラムを作る
各データは,空白文字で区切られる.
1列目の氏名と,3列目の住所を取り出すために
sscanf 関数を使う
金子邦彦 1200/01/01 福岡市東区箱崎 092-642-4068
○○×× 1300/12/31 福岡市東区貝塚 092-642-3883
●●■■ 800/05/31 福岡市東区香椎 092-642-3884
17
例題2.ファイルからのデータ読み込
#include <stdio.h>
#pragma warning(disable:4996)
int main()
{char line[100];
char name[100];
char birth[100];
char address[100];
FILE *in_file;
in_file = fopen("a=d:\\Book1.csv", "r");
if ( in_file == NULL ) {
printf( "fopen() error" );
return 0;
}
while( fgets( line, 100, in_file ) != NULL ) {
sscanf_s( line, "%s %s %s", name, birth, address );
printf( "name=%s, address=%s\n", name, address );
}
fclose(in_file);
return 0;
}
ファイルポインタ変数の宣言
ファイルのオープン
(ファイルポインタが得
られる)
ファイルのクローズ
(ファイルポインタを使ってクローズする)
ファイルのオープンに
失敗したかを調べている
ファイルの終わりに達し
ていないかを調べている
ファイルの
1行読み込み
1列目,2列目,3列目の取り出し
18
実行結果例
name=金子邦彦, address=福岡市東区箱崎
name=○○××, address=福岡市東区貝塚
name=●●■■, address=福岡市東区香椎
19
プログラムとデータ
メモリ
fgets( line, 100, in_file )
ファイルの
1行読み込み
line[0]
line[1]
line[99]
sscanf( line, "%s %s %s", name, birth, address );
1行分の表示
データの取り出し name birth address
printf( "name=%s, ...
20
プログラム実行順
in_file = fopen("d:\\Book1.csv", "r");
fgets( line, 100, in_file ) != NULL Yes
No
fclose(in_file);
sscanf( line, "%s %s %s", name, birth, address );
printf( "name=%s, address=%s\n", name, address );
21
sscanf 関数
line の中身を調べて,1列目,2列
目,
3列目のデータを name, birth,
address
に格納する
sscanf( line, "%s %s %s", name, birth, address );
○○×× 1300/12/31 福岡市東区貝塚 092-642-3883 1行分
1列目 2列目 3列目 4列目
22
例題3.1行単位のファイル書き出し
2つの浮動小数データを読み込んで,sin 関数
を使った計算を行い,計算結果をファイルに
書き出すプログラムを作る.
「0」と「0.1」を読み込むと,0, 0.1, … 1.9
について,sin関数を使った計算を繰り返す(繰り
返し回数は20回とする)
ファイルの書き出すでは,1行単位の書き出しを
行うために fprintf 関数を使う
書き出されたファイルは,Microsoft Excel で読
み込み可能な形式であること 23
#include <stdio.h>
#include <math.h>
struct compute {
double start_x;
double step_x;
};
void input_data( struct compute *data )
{
printf( "start_x =" );
scanf( "%lf", &(data->start_x) );
printf( "step_x =" );
scanf( "%lf", &(data->step_x) );
}
start_x step_x
キーボードから読み込む関数
24
void output_result( struct compute *data, char *file_name )
{
double x;
double y;
int i;
FILE* fp;
fp = fopen( file_name, "w" );
for( i = 0; i < 20; i++ ) {
x = data->start_x + ( i * data->step_x );
y = sin( x );
printf( "x= %lf, y= %lf\n", x, y );
fprintf( fp, "x=, %lf, y=, %lf\n", x, y );
}
fclose( fp );
}
start_x step_x を使って計算
を行い,結果をファイルに書き込む関数
25
int main()
{
struct compute data;
input_data( &data );
output_result( &data, "z:\\data.csv" );
return 0;
}
26
関数呼び出しの流れ
input_data 関数
void input_data( struct compute *data )
main 関数
int main()
input_data(&data
);
関数呼び出し
return;
戻り
output_result(&data,"z:\\data.csv")
;
関数呼び出し output_result 関数
void output_result( struct compute *data, char *file_name )
return;
戻り
27
1行単位のファイル読み込み
の手順
ファイルのオープン
ファイルのクローズ
fprintf 等を使って,
ファイルの1行書き出し
終わりか?
Yes No
28
テキストファイルの読み書き
読み込み
fgets sscanf を使って,1行単位で読み込み
書き出し
fprintf を使って,1行単位で書き出し
29
オープンモード
“r” モード
読み込みモード
引数fileで指定したファイルが存在しないか,読み
込み不可能な場合には,オープンすることができ
ない.
w” モード
書き出しモード
引数fileで指定したファイルが存在しない場合には,
ファイルが新たに作成される.ファイルがすでに
存在した場合,ファイル中のデータはすべて捨て
られる(ファイルの長さは0になる).
fopen( file_name, "w" );
ファイル名
(文字列)オープンモード
(文字列)
30
課題3.ファイルのコピー
ファイルをコピーするプログラムを作りなさ
ファイルを1行単位で読み込んで,別のファイルに1行
単位で書き出すことを繰り返す.
ファイルの読み込みでは,1行単位の読み込みを行う
ために fgets 関数を使う
ファイルの書き出しでは,1行単位での書き出しを行
うために fprintf関数を使う
2つのファイルを扱うために,2つのファイルポイン
タ変数の宣言を行うこと
読み込むべきファイルは,Zドライブに事前に作成して
おくこと
31