Fgets
[Wikipedia|▼Menu]

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

stdio.h で fgets は以下のような形式で宣言されている。char *fgets( char *restrict str, int count, FILE *restrict stream );

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

名称から 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 に置き換える場合に改行文字を除去する処理を加えておかなければ元のコードと同一の動作となる保証は無い。実際に入力データをfopensystem等の関数のパラメータとして渡す場合では文字列は末尾に改行文字があるとエラーとなる。
最大文字数を超えた入力に対する対処

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

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

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

実際に gets を fgets に置き換える場合は上記の事を考慮しなければならない、ここでは実際に gets を fgets に置き換える例を示す。具体的には gets を使用した以下のようなコードがあるとする、
gets.c
char a[20];if (gets(a) == NULL) { // エラー処理}

この時このコードを fgets に置き換えて、その後の処理に影響を与えないようにする場合は以下のようになる、
fgets.c
char a[20];if (fgets(a, sizeof a, stdin) == NULL) { // エラー処理}// 改行文字が含まれているかの確認char *p = strchr(a, '\n');// 改行文字を終端記号に置換するif (p != NULL) *p = '\0';// 入力ストリームをクリアするfor (int ch; (ch = getchar()) != EOF;) if (ch == '\n') break;

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

fgets は文字列を読み込む関数なので、当然ながら scanf の数値入力に対してそのまま置き換えることは出来ない。このような場合は fgets でまず文字列として取り込んだ後、sscanfを用いて入力することで置き換えることが出来る。例えばint i;if (scanf("%d", &i) != 1) { // エラー処理}

となるようなコードはint i;char temp[128]; // サイズはとりあえず適当に置いておくfgets(temp, sizeof temp, stdin);// バッファクリアの処理は省略if (sscanf(temp, "%d", &i) != 1) { // エラー処理}

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

標準Cライブラリ

gets

fputs

scanf

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

外部リンク

fgets(3)
 ? JM Project Linux Library Functions マニュアル










C言語


K&R

ANSI C

C89

C90


C99

C11

C17(英語版)

C2x(英語版)

Embedded C(英語版)

MISRA C

Cの機能
関数

ヘッダファイル

演算子

文字列(英語版)

文法(英語版)

プリプロセッサ(英語版)

データ型(英語版)

キーワード

フリースタンディング環境

標準Cライブラリの関数

ctype.h(英語版)

stdio.h

math.h(英語版)

stdlib.h(英語版)

string.h(英語版)

time.h

stdarg.h(英語版)

POSIXライブラリ(英語版)

標準Cライブラリ

Bionic(英語版)

libhybris(英語版)


dietlibc

EGLIBC

glibc

klibc(英語版)

マイクロソフトランタイムライブラリ(英語版)

musl

Newlib

uClibc

BSD libc

コンパイラ

ACK(英語版)

BDS-C

Clang

C++ Builder

gcc

Intel C++ Compiler

LCC(英語版)

LSI C-86

Pelles C(英語版)

PCC

TCC

Turbo C

Microsoft Visual C++

Watcom C/C++(英語版)

統合開発環境

Anjuta

Code::Blocks

CodeLite

Eclipse

Geany

Microsoft Visual Studio

NetBeans

CLion

派生言語

C++

Cg



D言語

Objective-C

Alef(英語版)

Limbo

Go

Vala

SystemC

Unified Parallel C

関連項目

IOCCC



カテゴリ

.mw-parser-output .asbox{position:relative;overflow:hidden}.mw-parser-output .asbox table{background:transparent}.mw-parser-output .asbox p{margin:0}.mw-parser-output .asbox p+p{margin-top:0.25em}.mw-parser-output .asbox{font-size:90%}.mw-parser-output .asbox-note{font-size:90%}.mw-parser-output .asbox .navbar{position:absolute;top:-0.90em;right:1em;display:none}


次ページ
記事の検索
おまかせリスト
▼オプションを表示
ブックマーク登録
mixiチェック!
Twitterに投稿
オプション/リンク一覧
話題のニュース
列車運行情報
暇つぶしWikipedia

Size:16 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)
担当:undef