ファイル記述子でなくFILEストリームを使いたい場合は fopen / fread / fwrite / fclose 関数を使うことができます。
とりえあえず関数の宣言から見てきましょう。
#include <stdio.h> FILE *fopen(const char *pathname, const char *mode); int fclose(FILE *stream); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
fopen の mode は以下の 6 種類あります。
FILEストリームは fprintf で使った stdout や stderr に相当するものです。
ストリームは FILE オブジェクトを指しているポインターなので、ファイル記述子とは別物です。
まあさして重要じゃないんで、実装例を軽く見るだけで良いでしょう。
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #define BUFFER_SIZE 8192
5
6 int main(int argc, char **argv)
7 {
8 int size;
9 FILE *stream;
10 char buf[BUFFER_SIZE];
11
12 if (argc != 2) {
13 fprintf(stderr, "ファイル名を指定してください\n");
14 exit(1);
15 }
16
17 stream = fopen(argv[1], "r");
18
19 if (stream == NULL) {
20 fprintf(stderr, "%s を開けませんでした\n", argv[1]);
21 exit(1);
22 }
23
24 size = 1;
25 while (size > 0) {
26 size = fread(buf, 1, BUFFER_SIZE, stream);
27 if (size > 0) {
28 fwrite(buf, 1, size, stdout);
29 }
30 }
31 fclose(stream);
32 return 0;
33 }ビルドと実行結果.
$ echo "abcde" > "abc.txt" $ echo "12345" >> "abc.txt" $ gcc main.c $ ./a.out abc.txt abcde 12345
まずは変数から説明しますかね。
8 int size; 9 FILE *stream; 10 char buf[BUFFER_SIZE];
size は fread() 関数の返り値を保持する変数として使います。
読みこんだバイトサイズですね。
stream は FILE オブジェクトを指すポインターです。
ここでは fopen() の返り値となりますが、読み込み専用の指定をしているので入力ストリームとでも読んでおきましょう。
17 stream = fopen(argv[1], "r");
ファイルシステムから読み込んだデータをメモリーへ保持するために使う変数が buf です。
24 size = 1;
25 while (size > 0) {
26 size = fread(buf, 1, BUFFER_SIZE, stream);
27 if (size > 0) {
28 fwrite(buf, 1, size, stdout);
29 }
30 }正直 BUFFER_SIZE が大きめなので while 文を使うまでもないんですけど、本当に大きいデータを読みこむならループにしておきます。
まず fread() が stream から BUFFER_SIZE バイトを読み込うとします。
それで size が 0 以上ならば fwrite() で標準出力をします。
この際に出力に使うサイズは fread の返り値を保持する size 変数を使っています。
Copyright 2018-2019, by Masaki Komatsu