はじめに
こんにちは、ダックです。
今回はソフトウェア研修中に C 言語を用いて、ファイルの読み込みを行いました。
ファイルは読み込むまで、中身がどうなっているかプログラムは知りません。
未知のファイルに出会ったとき、どうするか?
この記事ではファイルの長さをテーマに話を進めていきます。
また、今回は fscanf という関数を使い改行、スペースを含まないファイルを対象に読み込みと表示を行いました。
短いテキストファイルの読み込み
テキストファイルを読み込むために以下のソースコードを作りました。
【図 1】 test1 コード
動作内容は、
① fopen でテキストファイルを開く
② fscanf でテキストファイル内の文字列を読み込み確認のため printf で読み込んだ文字列を
コンソールに表示させる
③ fclose でテキストファイルを閉じる
となります。
試しに以下の 7 文字のファイルを読み込んでみました。
【図 2】 入力ファイル(read.txt)
【図 3】 test1 出力結果
正しくできました。
しかし、このコードには致命的な欠点があったのです。
文字列の長さは変えられない!?
もっと長い 14 文字ファイルを読み込みました。
【図 4】 入力ファイル(read.txt)
出力しました。
【図 5】 test1 出力結果
読み込んだ文字列が表示されず、エラーメッセージが出ています。
どうしてでしょう?
今回はファイルを読み込むための配列を str[10] としました。
つまり 10 文字分しかメモリを用意していません。
それを超えると文字を読み込むことができません。
【図 6】 文字列の読み込み
配列を定義するときには、始めに配列の長さを固定しなければなりません。
しかし、ファイルを読み込む場合、開いてみるまで中身の長さは分からないので、どれくらいのサイズが必要か分かりません。
だからと言って莫大なメモリを準備しておくことは、プログラム上無駄が多くなってしまいます。
ではどうすればいいのでしょうか?
希望の光 malloc
ここで、前回紹介したように、文字列を配列ではなくポインタを使い保存します。
【図 7】 test2 コード
ちょっと長くなりました。追加した点は主に以下の 2 点です。
① fseek でファイルの最後まで行きその場所までの長さを size に代入し先頭に戻る。
② malloc でサイズ分のメモリを確保する。
このように、ファイルを開いた後に、ファイル内の文字列の長さを確認します。
そのサイズ分のメモリを確保することで、最初に配列のサイズを指定しなくても、ファイルを読み込むことができます。
では、先ほどの【図 4】の 14 文字のファイルを出力してみましょう。
【図 8】 test2 出力結果
正しく出力されました。
なるほど、長さが分からない配列は malloc を使うことで、コードを書き終わった後に長さを変えることができるのですね。
ちなみに
malloc で確保したメモリ領域は使い終わったら必ず free 関数を用いて解放します。
もし、メモリを解放せずに使い続けると、メモリがいっぱいになって思わぬエラーを生じます。
今回のような少ないメモリ領域の確保なら問題ありませんが、領域をたくさん確保したり、大きな領域を確保する場合は忘れてはなりません。
【図 9】 free 使用例