/* * 20161209-02-QQQQ.c * * コマンドラインで指定した二つのファイルの中身を * 1 byte(文字) 単位で比較して、最初に異なった場所(先頭からの * byte 数) を表示する */ #include <stdio.h> /* * main */ int main ( int argc, char *argv[] ) { if ( argc != 3 ) { /* 引数が二つの場合 */ /* もし、コマンドラインに二つのファイル名を指定したら、 argc は 3 になるはず */ printf ( "ファイル名を二つ指定して下さい。\n" ); } else { FILE *fp1; /* 一つ目のファイルのファイルポインタ */ if ( ( fp1 = fopen ( argv[1], "r" ) ) == NULL ) { printf ( "ファイル(%s)を開く事ができませんでした。\n", argv[1] ); } else { FILE *fp2; /* 一つ目のファイルのファイルポインタ */ if ( ( fp2 = fopen ( argv[2], "r" ) ) == NULL ) { printf ( "ファイル(%s)を開く事ができませんでした。\n", argv[2] ); } else { int position; int ch1; int ch2; /* この for 文は ファイルの中身を 1 文字ずつすべて */ for ( position = 0; (ch1 = fgetc (fp1)) != EOF; position++ ) { ch2 = fgetc( fp2 ); if ( ch1 != ch2 ) { /* 文字が異なっていたら */ break; /* for 文を抜ける */ } } /* ch! != ch2 の時に break -> ここで違う文字をみつけた ch1 が EOF の時 -> もし、二つめのファイルも終わっていれば 同じ内容のファイル そうでなければ、 同じ内容のファイルに追加がある違う */ if ( ch1 == EOF ) { ch2 = fgetc( fp2 ); /* もし、同じファイルなら ch2 も EOF になる */ } if ( ch1 == ch2 ) { /* ch1 == ch2 == EOF の時 */ printf ( "二つのファイル(%s,%s)は同じ内容です。\n", argv[1], argv[2] ); } else if ( ch1 == EOF ) { /* ファイル2 の方が長かった */ printf ( "ファイル(%s) の方がサイズが大きいです。\n", argv[2] ); } else if ( ch2 == EOF ) { /* ファイル1 の方が長かった */ printf ( "ファイル(%s) の方がサイズが大きいです。\n", argv[1] ); } else { /* ファイル1 もファイル 2 も終わりじゃないのに違った */ printf ( "%d byte 目で %s は %c, %s は %c という違いがありました。\n", position, argv[1], ch1, argv[2], ch2 ); } fclose ( fp2 ); } fclose ( fp1 ); } } return 0; }
/* *ファイルに書き出すプログラム * * ファイルの内容の読み書きは * いったん、ファイルポインターを入手し、 * ファイルポインター経由で、操作を行う必要がある。 * 手順 * ファイルポインタを入手 * ファイルを開く(open) * ファイル操作(情報の R/W) * ファイルポインターを指定して、r/w の関数を呼ぶ * ファイルの利用が終わったら、ファイルポインターを開放 * ファイルの閉じる(close) */ /* ファイル abc.dat に、"abc" + 改行の 4 文字(4 byte) の 情報を書き込む */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; /* これから開く、ファイルへのファイルポインターを保存する */ /* 「*」がついているので、「ポインター型」である事が解る */ /* いくつファイルを開くは、あらかじめわからない */ /* 動的なデータ型 -> 裏で alloc がされている */ fp = fopen( "abc.dat", "w" ); /* ライブラリ関数 fopen を利用して、 ファイル "abc.dat" に対するファイルポインターを入手 */ /* ファイルがない場合は、自動的に作られる */ /* すでにファイルがある場合は、消される */ /* 何等かの理由で、ファイルのオープンに失敗した場合は、 NULL が値として帰る */ if ( fp != NULL ) { /* 無事オープンできたらデータを書き込む */ /* データを書き込む */ fprintf ( fp, "abc\n" ); /* ライブラリ関数 fprintf を利用して、 最初の引数に指定したファイルポインターに 対応するファイルに、print する */ fclose ( fp ); /* ライブラリィ関数 fclose を用いて、ファイルをクローズ */ /* 後処理を行い、(C 言語のレベルでは..) 記録を完了させる */ /* (free の時と同じように..) いったん close した、 ファイルポインタは使えなくなる もし、同じファイルを操作したければ、 もういちど、ファイルをオープンして、 別のファイルポインタを入手する必要がある */ } else { printf ( "ファイル(abc.dat)のオープンに失敗しました\n" ); } return 0; }
#include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; fp = fopen( "abc.dat", "w" ); fprintf ( fp, "abc\n" ); fclose ( fp ); return 0; }
/* *ファイルデータ読み出すプログラム * */ /* ファイル xyz.dat から情報を読み込む */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; fp = fopen( "abc.dat", "r" ); if ( fp != NULL ) { /* fscanf ( fp, "%s", read_buffer ); */ putchar ( fgetc ( fp ) ); /* 最初の一文字を読み出し、画面 */ putchar ( fgetc ( fp ) ); /* 最初の一文字を読み出し、画面 */ putchar ( fgetc ( fp ) ); /* 最初の一文字を読み出し、画面 */ putchar ( fgetc ( fp ) ); /* 最初の一文字を読み出し、画面 */ fclose ( fp ); /* ファイルをクローズ */ printf ( "読み込んだデータ : 「%s」\n", read_buffer ); } else { printf ( "ファイル(abc.dat)のオープンに失敗しました\n" ); } return 0; }
#include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; char read_buffer[5]; fp = fopen( "abc.dat", "r" ); fscanf ( fp, "%s", read_buffer ); fclose ( fp ); printf ( "読み込んだデータ : 「%s」\n", read_buffer ); return 0; }
/* *ファイルに書き出すプログラム * fputc 版 ( 一文字ずつかく ) */ /* ファイル abc.dat に、"abc" + 改行の 4 文字(4 byte) の 情報を書き込む */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; fp = fopen( "xyz.dat", "w" ); if ( fp != NULL ) { fputc ( 'x', fp ); /* fprintf ( fp, "abc\n" ) */ fputc ( 'y', fp ); fputc ( 'z', fp ); fputc ( '\n', fp ); fclose ( fp ); } else { printf ( "ファイル(xyz.dat)のオープンに失敗しました\n" ); } return 0; }
/* *ファイルに書き出すプログラム * fputc 版 ( 一文字ずつかく ) */ /* ファイル abc.dat に、"abc" + 改行の 4 文字(4 byte) の 情報を書き込む */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; fp = fopen( "xyz.dat", "r" ); if ( fp != NULL ) { putchar ( fgetc ( fp ) ); putchar ( fgetc ( fp ) ); putchar ( fgetc ( fp ) ); putchar ( fgetc ( fp ) ); fclose ( fp ); } else { printf ( "ファイル(xyz.dat)のオープンに失敗しました\n" ); } return 0; }
/* *ファイルに書き出すプログラム * fputc 版 ( 一文字ずつかく ) */ /* ファイル abc.dat に、"abc" + 改行の 4 文字(4 byte) の 情報を書き込む */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; int ch; /* 読み込んだ 1 文字のデータを記録 */ fp = fopen( "xyz.dat", "r" ); if ( fp != NULL ) { while ( (ch = fgetc ( fp )) != EOF ) { /* 「(ch = fgetc ( fp )) != EOF」 ch = fgetc ( fp ) 代入をしてから ch != EOF その値が EOF かどうかをチェック EOF は、End Of File の意味で、 ファイルから読み出しを行う場合に、 すでにすべての byte が読みだされているときに、 特別な EOF を返す ファイルの中に文字がある限り その文字をすべて読み出し、その結果を表示 */ putchar ( ch ); } fclose ( fp ); } else { printf ( "ファイル(xyz.dat)のオープンに失敗しました\n" ); } return 0; }
/* *ファイルに書き出すプログラム * fputc 版 ( 一文字ずつかく ) */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; int ch; /* 読み込んだ 1 文字のデータを記録 */ fp = fopen( argv[1], "r" ); /* コマンドライン引数にファイル名が指定されている */ if ( fp != NULL ) { while ( (ch = fgetc ( fp )) != EOF ) { /* 「(ch = fgetc ( fp )) != EOF」 ch = fgetc ( fp ) 代入をしてから ch != EOF その値が EOF かどうかをチェック EOF は、End Of File の意味で、 ファイルから読み出しを行う場合に、 すでにすべての byte が読みだされているときに、 特別な EOF を返す ファイルの中に文字がある限り その文字をすべて読み出し、その結果を表示 */ putchar ( ch ); } fclose ( fp ); } else { printf ( "ファイル(xyz.dat)のオープンに失敗しました\n" ); } return 0; }
/* *ファイルに書き出すプログラム * * fwrite 版 */ /* ファイル pqr.dat に、"pqr" + 改行の 4 文字(4 byte) の 情報を書き込む */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; fp = fopen( "pqr.dat", "w" ); if ( fp != NULL ) { /* 無事オープンできたらデータを書き込む */ /* データを書き込む */ /* fprintf ( fp, "abc\n" ); */ fwrite ( "pqr\n", 4, 1, fp ); /* 最初の引数で指定したポインタの場所の値を 4 byte のデータだと思い、1 個だけ書き出す */ fclose ( fp ); } else { printf ( "ファイル(pqr.dat)のオープンに失敗しました\n" ); } return 0; }
/* *ファイルに書き出すプログラム * * fwrite 版 */ /* ファイル pqr.dat に、"pqr" + 改行の 4 文字(4 byte) の 情報を書き込む */ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; char read_buffer[5]; fp = fopen( "pqr.dat", "r" ); if ( fp != NULL ) { fread ( read_buffer, 4, 1, fp ); /* 最初の引数で指定したポインタの場所の値を 4 byte のデータだと思い、1 個だけ読み込む */ /* read_buffer には EOS がない */ fclose ( fp ); read_buffer[4] = '\0'; /* EOS を追加 */ printf ( "データ = 「%s」\n", read_buffer ); } else { printf ( "ファイル(pqr.dat)のオープンに失敗しました\n" ); } return 0; }
#include <stdio.h> /* ファイル number.dat の中の数値の合計を計算 */ int main(int argc, char *argv[] ) { FILE *fp; int sum = 0; int num; if ( ( fp = fopen ( "number.dat", "r" ) ) != NULL ) { while ( fscanf ( fp, "%d", &num ) > 0 ) { sum = sum + num; } fclose ( fp ); printf ( "合計 : %d\n", sum ); } else { printf ( "ファイル(number.dat)が開けません\n" ); } }
#include <stdio.h> int main(int argc, char *argv[] ) { FILE *fp; int sum = 0; int num; if ( ( fp = fopen ( "number2.dat", "w" ) ) != NULL ) { num = 123000; fwrite ( &num, sizeof ( int ), 1, fp ); /* 整数型変数の値を、直接書き込む */ /* fpintf/fscanf -> 値を文字列に変換 */ num = 456000; fwrite ( &num, sizeof ( int ), 1, fp ); num = 999000; fwrite ( &num, sizeof ( int ), 1, fp ); num = 111000; fwrite ( &num, sizeof ( int ), 1, fp ); fclose ( fp ); } else { printf ( "ファイル(number.dat)が開けません\n" ); } }
#include <stdio.h> /* ファイル number.dat の中の数値の合計を計算 */ int main(int argc, char *argv[] ) { FILE *fp; int sum = 0; int num; if ( ( fp = fopen ( "number2.dat", "r" ) ) != NULL ) { while ( fread ( &num, sizeof(int), 1, fp ) > 0 ) { sum = sum + num; } fclose ( fp ); printf ( "合計 : %d\n", sum ); } else { printf ( "ファイル(number2.dat)が開けません\n" ); } }
123 456 789
123 456 789
123 456 7890
123 456 78
123 4*6 789
FILE コンピュータの中で、情報を記録している単位 外部記憶装置であるハードディスクの一部に対応している ファイルシステムがあり、コンピュータが管理 C 言語のプログラムで、ファイルを操作したい 操作: 作成/参照/削除/変更/移動/etc.. (普段 PC でやっていること) 実は、全部できる 今日は : ファイルの作成(内容の作成)と内容の参照 -> 変数の拡張 データをファイルに書き出す -> 変数への代入 データをファイルから読み込む -> 変数の参照 -> ファイルを利用する : 変数の機能が拡張される 時間方向 : プログラムの終了のちも残る 空間方向 : より、多くなサイズのデータが扱える トレードオフ : 速度が(ハードディスクだと) 2 桁位遅い 変数に対する操作(宣言、代入、参照)は C 言語の基本機能 -> 基本機能で実現される FILE Input/Ouput (I/O) -> C 言語の基本機能ではない -> C 言語の基本ライブラリィの関数で行う cf. 動的メモリ管理も malloc/free という C 言語の標準ライブラリを使った # ライブラリィを使う -> ライブラリ固有のルールを守る必要がある cf. alloc した領域は、free する必要がある FILE I/O も同様にルールがあるので守る必要がある ファイルポインタを対象にした I/O 関数 fprintf fscanf 画面とキーボード(標準出力、標準入力) に対する printf/scanf と同じ putchar, getchar : 一文字単位の I/O -> これのファイルポインター版がある fgetc / fputc
追加はなし