本記事C言語の標準入出力(シーげんごのひょうじゅんにゅうしゅつりょく)では、C言語で提供される、ファイル入出力用の、標準Cライブラリヘッダ <stdio.h>[1] の大部分を構成する標準Cライブラリ関数について述べる。これらの機能は、1970年代初頭[2]ベル研究所マイク・レスク英語版によって書かれた、「ポータブルI/Oパッケージ」に由来し、正式にVersion 7 UnixUnixオペレーティングシステムの一部になった[3]

C言語の標準入出力機能は、現代使われるプログラミング言語の中ではかなり貧弱であり、すべてのファイル操作をバイトストリーム (「入力ストリーム」あるいは「出力ストリーム」) の操作に抽象化する。C言語以前のプログラミング言語とは異なり、C言語はランダムアクセスを直接サポートしていない。ファイルの途中から読み取るには、プログラマは、ストリームを作成し、ファイルの途中へシークし、ストリームからバイトを順番に読み取らなければならない。

ファイル入出力のストリームモデルは、C言語とほぼ同時に開発されたUnixによって普及した。最近のオペレーティングシステムの大部分はUnixのストリームモデルを継承している。また、C言語の影響を受けた多くの言語はC言語のファイル入出力インターフェイスを継承しており、差異はほぼ存在しない (例: PHP)。

概要 編集

C言語の標準入出力機能は、ストリームと呼ばれるオブジェクトを使用して、キーボード、プリンタ、端末などの物理デバイス、またはシステムでサポートされている他の種類のファイルを操作する。ストリームは、これらのデバイスを 同じ操作で操作するための抽象化に利用される。すなわち、すべてのストリームは、関連付けられている物理デバイスの差異に関係なく、同様のプロパティを持つ[4]

関数 編集

ほとんどのC言語入出力関数は、stdio.h (または、C++の場合 cstdio 上の std 名前空間) に定義されている。

C言語の標準入出力関数一覧
機能 バイト
文字
ワイド
文字
説明
ファイル
アクセス
fopen ファイルを開く (Windows上では非Unicodeファイル名、Linux上ではUTF-8ファイル名を使用可能)
freopen 既存のストリームで別のファイルを開く
fflush 出力ストリームを実際のファイルと同期する
fclose ファイルを閉じる
setbuf ファイルストリームのバッファを設定する
setvbuf ファイルストリームのバッファとサイズを設定する
fwide ファイルストリームの入出力単位を設定または取得する  
直接入出力 fread ファイルから読み取る
fwrite ファイルに書き込む
非フォーマット
入出力
fgetc
getc
fgetwc
getwc
ファイルストリームからバイトまたはワイド文字を読み取る
fgets fgetws ファイルストリームからバイトまたはワイド文字列を1行読み取る
fputc
putc
fputwc
putwc
ファイルストリームにバイトまたはワイド文字を書き込む
fputs fputws ファイルストリームにバイトまたはワイド文字列を書き込む
getchar getwchar 標準入力ストリームからバイトまたはワイド文字を読み取る
gets N/A 改行またはファイルの終端に達するまで、標準入力ストリームからバイト文字列を読み取る (C99で非推奨、C11で削除)
putchar putwchar 標準出力ストリームにバイトまたはワイド文字を書き込む
puts N/A 標準出力ストリームにバイト文字列を書き込む
ungetc ungetwc バイトまたはワイド文字をファイルストリームに戻す
フォーマット
入出力
scanf
fscanf
sscanf
wscanf
fwscanf
swscanf
標準入力ストリーム、ファイルストリーム、またはバッファからフォーマットされたバイトまたはワイド文字列を読み取る
vscanf
vfscanf
vsscanf
vwscanf
vfwscanf
vswscanf
可変長引数リストを使用して、標準入力ストリーム、ファイルストリーム、またはバッファからフォーマットされたバイトまたはワイド文字列を読み取る
printf
fprintf
sprintf
snprintf
wprintf
fwprintf
swprintf
標準出力ストリーム、ファイルストリーム、またはバッファにフォーマットされたバイトまたはワイド文字列を出力する
vprintf
vfprintf
vsprintf
vsnprintf
vwprintf
vfwprintf
vswprintf
可変長引数リストを使用して、標準出力ストリーム、ファイルストリーム、またはバッファにフォーマットされたバイトまたはワイド文字列を出力する
perror N/A 現在のエラーの説明を標準エラーストリームに書き込む
ファイル

位置操作

ftell
ftello
現在のファイル位置指示子を取得する
fseek
fseeko
ファイル内の任意の位置にファイル位置指示子を移動する
fgetpos 現在のファイル位置指示子を取得する
fsetpos ファイル内の任意の位置にファイル位置指示子を移動する
rewind ファイル位置指示子をファイルの先頭に移動する
エラー

ハンドリング

clearerr エラーをクリアする
feof ファイルの終端かチェックする
ferror ファイルのエラーをチェックする
ファイル

操作

remove ファイルを削除する
rename ファイルの名前を変更する
tmpfile 一時ファイルのストリームを作成する
tmpnam 一時ファイルの名前を作成する

定数 編集

stdio.h で定義されている定数は次の通りである。

定数名 説明
EOF ファイルの終端を表現する、int 型の負の整数
BUFSIZ setbuf 関数に渡すバッファの大きさを表す定数
FILENAME_MAX 処理系が許すファイル名の char 型配列としての最大長
FOPEN_MAX 同時に開くことのできるファイル数、最低で8
_IOFBF setvbuf 関数にフルバッファリングを行うことを要求する際使用する整数
_IOLBF setvbuf 関数に行バッファリングを行うことを要求する際使用する整数
_IONBF setvbuf 関数にバッファリングを行なわないことを要求する際使用する整数
L_tmpnam tmpnam 関数が生成するファイル名を保持するために必要なchar 型配列の大きさを表す。
NULL NULLポインター定数に展開されるマクロ。メモリ内の有効なオブジェクトのアドレスではないことが保証されているポインタ値を表す定数
SEEK_CUR fseek 関数にファイルの現在位置を基準に位置変更を行うことを要求する際使用する整数
SEEK_END fseek 関数にファイルの終端位置を基準に位置変更を行うことを要求する際使用する整数
SEEK_SET fseek 関数にファイルの先頭位置を基準に位置変更を行うことを要求する際使用する整数
TMP_MAX tmpnam 関数で生成可能な一意のファイル名の最大数、最低で25

変数 編集

stdio.h で定義されている変数は次の通りである。

名前 説明
stdin 標準入力ストリーム (通常はキーボード) を参照する FILE 型へのポインタ
stdout 標準出力ストリーム (通常は表示する端末) を参照する FILE 型へのポインタ
stderr 標準エラーストリーム (通常は表示する端末) を参照する FILE 型へのポインタ

データ型 編集

stdio.h で定義されているデータ型は次の通りである。

  • FILE – ファイルハンドルとしても知られている。入出力操作を実行するために必要な以下のようなファイルまたはテキストストリームに関する情報を保持しているプログラマから隠蔽された型である。
    • ファイル記述子など、関連する入出力デバイスのプラットフォーム固有の識別子
    • バッファ
    • ストリームの方向の状態
    • バッファ状態
    • 入出力状態
    • モード (バイナリもしくはテキスト)
    • EOF状態
    • エラー状態
    • 現在位置とマルチバイト変換状態
    • 再入可能ロック (C11では必須)
  • fpos_t – ファイル内の位置を表す型
  • size_tsizeof 演算子の結果の型であり、符号なし整数型

拡張機能 編集

POSIX標準では、stdio に拡張を定義している。それによって、readline 関数を使用してメモリを自動で割り当てること、fileno 関数と fdopen 関数を使用して、FILE 型とファイル記述子を接続すること、メモリ上を参照するFILE型の参照を作成することが可能になる[5]

編集

以下のCプログラムでは、 hogefile というバイナリファイルを開き、5バイト読み取り、ファイルを閉じている。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char buffer[5];
    FILE* fp = fopen("hogefile", "rb");

    if (fp == NULL) {
        perror("\"hogefile\"を開けませんでした。");
        return EXIT_FAILURE;
    }

    for (int i = 0; i < 5; i++) {
        int rc = getc(fp);
        if (rc == EOF) {
            fputs("ファイルの読み取り中にエラーが発生しました。\n", stderr);
            return EXIT_FAILURE;
        }
        
        buffer[i] = rc;
    }

    fclose(fp);

    printf("読み取ったバイト列: %x %x %x %x %x\n", buffer[0], buffer[1],
        buffer[2], buffer[3], buffer[4]);

    return EXIT_SUCCESS;
}

stdioの代替 編集

stdio の代替がいくつか開発されている。これらの中には、ISO C++標準の一部である iostream ライブラリがある。

他には、ベル研究所が開発しているSfio (Safe-fast / string-file I/O) ライブラリがある。1991年に開発されたこのライブラリは、stdio の設計における矛盾、危険な慣行、非効率性を回避することを目的にしている。特徴として、コールバック関数を導入してストリームに対して読み書きを行い、より柔軟にデータ処理を行うことを可能とすることが挙げられる[6]。1997年に外部に公開された[7]

関連項目 編集

脚注 編集

  1. ^ ISO/IEC 9899:1999 specification. p. 274, § 7.19. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf 
  2. ^ Kernighan, Brian英語版; Pike, Rob (1984). The UNIX Programming Environment英語版. Englewood Cliffs英語版: Prentice Hall英語版. p. 200 
  3. ^ McIlroy, M. D. [in 英語] (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (Technical report). CSTR. Bell Labs. 139。
  4. ^ http://www.cplusplus.com/reference/cstdio/
  5. ^ stdio.h – The Open Group基本仕様書第7号2018年版「基本的な定義」
  6. ^ Korn, David G. [in 英語]; Vo, Kiem-Phong (1991). SFIO: Safe/Fast String/File IO. Proc. Summer USENIX Conf. CiteSeerX 10.1.1.51.6574
  7. ^ Fowler, Glenn S.; Korn, David G.; Vo, Kiem-Phong (2000). Extended Formatting with Sfio. Proc. Summer USENIX Conf.

外部リンク 編集