こんにちは、ダックです。


今回はソフトウェア研修中に C 言語を用いて、ファイルの読み込みを行いました。

ファイルは読み込むまで、中身がどうなっているかプログラムは知りません。

未知のファイルに出会ったとき、どうするか?

この記事ではファイルの長さをテーマに話を進めていきます。

また、今回は fscanf という関数を使い改行、スペースを含まないファイルを対象に読み込みと表示を行いました。

短いテキストファイルの読み込み

テキストファイルを読み込むために以下のソースコードを作りました。

test1コード

動作内容は

 

1. fopen でテキストファイルを開く

2. fscanf でテキストファイル内の文字列を読み込み確認のため printf で読み込んだ文字列をコンソールに表示させる

3. fclose でテキストファイルを閉じる

 

となります。

試しに以下の7文字のファイルを読み込んでみました。

入力ファイル (read.txt)

test1出力結果

正しくできました。

しかし、このコードには致命的な欠点があったのです。

文字列の長さは変えられない!?

もっと長い14 文字ファイルを読み込みました。

入力ファイル (read.txt)

出力しました。

test1出力結果

読み込んだ文字列が表示されず、エラーメッセージが出ています。

どうしてでしょう。

今回はファイルを読み込むための配列を str[10] としました。

つまり 10 文字分しかメモリを用意していません。

それを超えると文字を読み込むことができません。

文字列の読み込み

配列を定義するときには、始めに配列の長さを固定しなければなりません。

しかし、ファイルを読み込む場合、開いてみるまで中身の長さは分からないので、どれくらいのサイズが必要か分かりません。

だからと言って莫大なメモリを準備しておくことは、プログラム上無駄が多くなってしまいます。

ではどうすればいいのでしょうか。

希望の光 malloc

ここで、前回紹介したように、文字列を配列ではなくポインタを使い保存します。

test2コード

ちょっと長くなりました。追加した点は主に以下の2点です。

 

1. fseek でファイルの最後まで行きその場所までの長さを size に代入し先頭に戻る。

2. malloc でサイズ分のメモリを確保する。

 

このように、ファイルを開いた後に、ファイル内の文字列の長さを確認します。

そのサイズ分のメモリを確保することで、最初に配列のサイズを指定しなくても、ファイルを読み込むことができます。

では、先ほどの 図 4 の 14 文字のファイルを出力してみましょう。

test2出力結果

正しく出力されました。

なるほど、長さが分からない配列は malloc を使うことで、コードを書き終わった後に長さを変えることができるのですね。

ちなみに

malloc で確保したメモリ領域は使い終わったら必ず free 関数を用いて解放します。

もし、メモリを解放せずに使い続けると、メモリがいっぱいになって思わぬエラーを生じます。

今回のような少ないメモリ領域の確保なら問題ありませんが、領域をたくさん確保したり、大きな領域を確保する場合は忘れてはなりません。

free 使用例

ダックのC言語 関連記事

組み込みシステムには欠かせないC言語その基礎を分かりやすく解説! 

初期値問題 ver.C言語
初期値忘れがトラブルの原因に!? 

実は同一人物!?配列とポインタ
配列とポインタ、似ているようで違うこの二つを使い分ける! 

malloc~未知への挑戦~
C言語の特徴ともいえる、メモリの使い方について解説! 

人には読めない?バイナリファイルの謎
文字として読めないそのファイルの中身には何がある!?