今回はデータの読み込みについて書きます。
読み込みについての流れも基本的な部分は書き込みと同じです。
1.ファイルを開く 2.開けたかどうかチェックする 3.データを読み込む 4.ファイルを閉じる |
読み込む際にもファイルは開かなければなりませんし、閉じなければなりません。
早速作りたいと思いますが、出来れば新しいプロジェクトを作成してください。
まずは「データを読み込む」以外の箇所について作っていきます。
<sample program 111-01>
#include <stdio.h> int main(void) { FILE* fp; /* ファイルを開く */ fp = fopen("Test.txt", "r"); /* エラーチェック */ if (fp == NULL) { printf("OPEN ERROR\n"); return 1; } /* データを読み込む */ /* ファイルを閉じる */ fclose(fp); return 0; } |
「データを書き込む」プログラムとは異なる箇所があります。
fopen関数の第2引数が「"w"」から「"r"」に変わっています。
ファイルを開く時のモードを「write(書き込み)」から「read(読み込み)」に変えました。
とりあえず、この状態で実行してみましょう。
<実行結果>
OPEN ERROR 続行するには何かキーを押してください・・・
オープンエラーの表示が出ているということはファイルを開くのに失敗したということですね・・・
私は今回のプログラムを「Project02」というプロジェクトで作成しました。
私のフォルダの中身を見てください↓
開こうとしている「Test.txt」はここには存在していません。
存在していないものを開こうとしたのでエラーになったということです。
でも、ちょっと考えてください。
前の「データを書き込む」プログラムの時にも「Test.txt」を自分で作った覚えはありません。
プログラムを実行したら勝手に出来たのです。
※確認したい場合は、前のプロジェクトを開き、すでにある「Test.txt」を削除してから、再度プログラムを実行してみてください。
さて、この違いは何なのでしょうか・・・
答えは、「モードの違い」によるものです。
・「"w"」(書き込み)モードの場合 ファイルが無くても、書き込むために新規作成される。 ・「"r"」(読み込み)モードの場合 ファイルが無ければ、読み込めないのでエラーとなる。
ファイルがあればエラーになりませんので、ファイルを配置しましょう。
前のプログラムを実行して出来た「Test.txt」を、今のプロジェクトへコピーしてください。
コピー後のプロジェクトフォルダ↓
コピー後の「Test.txt」の中身↓
この状態で実行してみましょう。
<実行結果>
続行するには何かキーを押してください・・・
エラーは出なくなりましたね。
では、データの読み込みについて書きます。
ファイルから読み込まれたデータは適切な変数や配列に入れる必要があります。
型が分からないと変数などが準備出来ませんので、まずは読み込むデータに注目します。
「Test.txt」の中身は、
Hello 123
でした。
Helloは文字なので、文字列として読み込むためにchar型の配列を準備します。
とりあえずサイズは大きく取りましょう。
データの読み込みにはfscanf関数を使います。
<sample program 111-02>
#include <stdio.h> int main(void) { char str[20]; FILE* fp; /* ファイルを開く */ fp = fopen("Test.txt", "r"); /* エラーチェック */ if (fp == NULL) { printf("OPEN ERROR\n"); return 1; } /* データを読み込む */ fscanf(fp, "%s", str); /* ファイルを閉じる */ fclose(fp); return 0; } |
fscanf関数も最初の引数がファイルポインタであること以外はscanf関数と同じです。
とりあえず実行してみましょう。
<実行結果>
続行するには何かキーを押してください・・・
printf関数などは使っていませんので、何も表示されません。
本当にstrにデータが入っているかどうか確かめるため、printfを使って表示します。
<sample program 111-03>
#include <stdio.h> int main(void) { char str[20]; FILE* fp; /* ファイルを開く */ fp = fopen("Test.txt", "r"); /* エラーチェック */ if (fp == NULL) { printf("OPEN ERROR\n"); return 1; } /* データを読み込む */ fscanf(fp, "%s", str); /* ファイルを閉じる */ fclose(fp); printf("%s\n", str); return 0; } |
<実行結果>
Hello 続行するには何かキーを押してください・・・
ちゃんと「Hello」が入っていました!
・・・が、「Hello」の後ろにあった「123」はどこへいったのでしょう?
コラム「scanfと文字列」にも書いたと思いますが、scanf系の関数は半角空白を「区切り文字」として認識します。
fscanf関数で読み込む場合、「Test.txt」のデータ
Hello 123
は、
Hello
と
123
という2つのデータとして扱われるということです。
実際に2つ目のデータを数値として読み込んでみます。
<sample program 111-04>
#include <stdio.h> int main(void) { char str[20]; int data; FILE* fp; /* ファイルを開く */ fp = fopen("Test.txt", "r"); /* エラーチェック */ if (fp == NULL) { printf("OPEN ERROR\n"); return 1; } /* データを読み込む */ fscanf(fp, "%s", str); fscanf(fp, "%d", &data); /* ファイルを閉じる */ fclose(fp); printf("%s\n", str); printf("%d\n", data); return 0; } |
<実行結果>
Hello 123 続行するには何かキーを押してください・・・
2つ目のデータをint型のdataという変数に読み込み、表示しました。
fscanfでデータを読み込む場合には、以下の点に注意してください。
データは半角空白や改行で区切られるということ
データに合わせた変数や配列を準備すること