Fgetsとは? わかりやすく解説

fgets

(PHP 4, PHP 5)
fgets — ファイルポインタから 1 行取得する

説明

string fgets ( resource handle [, int length] )
handle で指定したファイルポインタから最大 length - 1 バイト読み出し、 その文字列を返します。読み出しは、length - 1 バイト読み出したか、(返り値に含まれる) 改行文字を検出したか、EOF に達したかのいずれかが起こった時点で終了します。 length が指定されない場合は、行末に達するまで読み続けます。
エラーが起こった場合、FALSE を返します。
陥りやすい罠:
C 言語の fgets の動作に慣れている人は、EOF を返す条件の違いについて 注意する必要があります。
ファイルポインタは、有効なファイルポインタである必要があり、 fopen() または fsockopen() で正常にオープンされた (そしてまだ fclose() でクローズされていない) ファイルを指している必要があります。
簡単な例を以下に示します。 例 595. 行毎にファイルを読み込む
<?php
$handle = @fopen("/tmp/inputfile.txt", "r");
if ($handle) {
   while (!feof($handle)) {
       $buffer = fgets($handle, 4096);
       echo $buffer;
   }
   fclose($handle);
}
?>


注意: length パラメータは、 PHP 4.2.0 でオプションとなりました。 PHP 4.3 より前のバージョンでは、もしこのパラメータが省略された場合、 行の長さを 1024 と仮定していました。 もしもファイル内の行の多くが 8KB を超えている場合、 行の長さの最大値を特定するためにスクリプトはリソースの影響を より大きく受けることになります。
fgetss()fread()fgetc()stream_get_line()fopen()popen()fsockopen() および stream_set_timeout() も参照ください。

fgets

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/10/12 00:14 UTC 版)

fgetsC言語標準Cライブラリにおける、標準入出力ヘッダー(<stdio.h>)で宣言されている FILEポインタから1行分の文字列を取り出す入力関数である。

形式

stdio.h で fgets は以下のような形式で宣言されている。

char *fgets(char *s, int n, FILE *stream)

fgets は stream が示すファイルから改行('\n')または n-1 バイト目まで文字を読み込み、引数で渡された s に格納する。この n-1 バイトの中には改行自体も含まれる。その後文字列の末尾に終端記号 '\0' を付与する。戻り値は stream の先頭が EOF だった場合もしくは途中でエラーが起こった場合は NULL、それ以外の場合は s である。

名称から getsのファイル読み込み版のように思われるが、fgets は gets と異なり引数に最大読み込み文字数を指定する。また gets は末尾の改行を終端記号に置き換えるのに対し、fgets は改行の後ろに終端記号を付与するという点が異なる。

gets や scanf の代替として用いる場合

fgets は本来ファイルから文字列を取り出すことを目的とした関数であるが、最大文字列数を引数に指定する事ができるためバッファオーバーランが発生しにくく、また入力された文字数が最大文字数を超えた場合でも末尾に終端記号が付与されることが保証されている等、標準Cライブラリの中ではかなりセキュアな構造となっているといえる。

これに対し、標準入力用に用意されている関数の中で fgets と同様の機能を実現するものとしてgetsscanfがあるが、getsは最大文字数を指定できないためバッファオーバーランが防ぐ手段が存在せず、scanfは文字幅指定できるが省略可能であるため開発者のミスで書き忘れる危険性がある等、安全性に問題点を持つものが多い。

このため fgets を標準入力用の関数として gets や scanf の代替として用いることが推奨されている[1][2]。ただし、fgets を標準入力関数の代替として用いる場合は下記に宣べるような点に注意しなければならない。

改行文字の扱い

fgets は gets や scanf と異なり改行文字も 1文字として数える。このため scanf や gets を fgets に置き換える場合に改行文字を除去する処理を加えておかなければ元のコードと同一の動作となる保証は無い。実際に入力データをfopenやsystem等の関数のパラメータとして渡す場合では文字列は末尾に改行文字があるとエラーとなる。

最大文字数を超えた入力に対する対処

gets 関数は改行文字が入力されるまで標準入力を読み続けるため、入力終了後にストリーム上に文字が残る事は無い、しかし fgets に置き換えた場合最大文字数を超えた入力が行われた場合、n バイト以降は入力ストリームにそのまま残されてしまい、後から別の入力を行うときに誤作動を起こす可能性がある。

scanf では代入抑止を使用することで入力ストリームをクリアする方法がある(参照)が、fgets にはそのような機能は無いため別途入力ストリームをクリアする処理を追加する必要がある。

また fgets で最大文字数を超える入力があった場合には、戻り値はエラーを返しては来ないので、入力された文字列に改行文字が含まれるかどうかで判断する必要がある。

getsを置き換える例

実際に gets を fgets に置き換える場合は上記の事を考慮しなければならない、ここでは実際に gets を fgets に置き換える例を示す。具体的には gets を使用した以下のようなコードがあるとする、

char a[20];

if (gets(a) == NULL) {
    // エラー処理
}

この時このコードを fgets に置き換えて、その後の処理に影響を与えないようにする場合は以下のようになる、

char a[20];

if (fgets(a, 20, stdin) == NULL) {
    // エラー処理
}

// 改行文字が含まれているかの確認
if (strchr(a, '\n') != NULL) {
    // 改行文字を終端記号に置換する
    a[strlen(a) - 1] = '\0';
} else {
    // 入力ストリームをクリアする
    while(getchar() != '\n');
}

入力ストリームは改行文字を読むまで getchar関数を繰り返して呼び出すことで実現している。ちなみに本格的にセキュリティを考慮する場合には上記のコードにさらにストリームクリア時にエラーが発生した場合などの処理も加える必要があるが本稿の趣旨と外れるのでここでは割愛する。

sscanf との連携

fgets は文字列を読み込む関数なので、当然ながら scanf の数値入力に対してそのまま置き換えることは出来ない。このような場合は fgets でまず文字列として取り込んだ後、sscanfを用いて入力することで置き換えることが出来る。例えば

int i;

if (scanf("%d", &i) != 1) {
    // エラー処理
}

となるようなコードは

int i;
char temp[128]; // サイズはとりあえず適当に置いておく

fgets(temp, 128, stdin);
// バッファクリアの処理は省略

if (sscanf(temp, "%d", &i) != 1) {
    // エラー処理
}

とすることで置き換えることが出来る。ただし、このように置き換えた場合には読み込むバッファの長さが十分であるという事を考慮しなければならない。また複数の数値を読み込む書式ではエラー処理のパターンが異なる(scanf#異常な入力が行われた時の処理を参照)ため、その事を十分認識しておく必要がある。

関連項目

脚注

  1. ^ Man page of GETS”. JMプロジェクト (2014年1月24日). 2016年11月27日閲覧。 “代わりに fgets() を使うこと。”
  2. ^ http://www.kouno.jp/home/c_faq/c12.html#20

外部リンク




固有名詞の分類


英和和英テキスト翻訳

英語⇒日本語日本語⇒英語

辞書ショートカット

すべての辞書の索引

「Fgets」の関連用語

Fgetsのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



Fgetsのページの著作権

   
PHP Documentation GroupPHP Documentation Group
Copyright © 1997 - 2026 by the PHP Documentation Group.
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのfgets (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2026 GRAS Group, Inc.RSS