C言語プログラミング:fputs 関数で実現するファイル入出力の多様な活用例
構文
int fputs(const char *str, FILE *stream);
引数
stream
: 出力先のファイルストリームを指すFILE
構造体ポインタstr
: 出力する文字列を含むNULL
文字で終端された文字列ポインタ
戻り値
正常に動作した場合、fputs
関数は書き込まれたバイト数を返します。エラーが発生した場合、EOF
を返します。
詳細
- バイナリモードで開かれているストリームに
fputs
関数を使用すると、予期しない結果が生じる可能性があります。 fputs
関数は、ストリームがテキストモードで開かれている場合、出力される文字列の末尾に改行 (\n
) 文字を追加しません。- エラーが発生した場合、
stream
のエラーインジケータが設定されます。 NULL
文字 (\0
) は書き込まれません。fputs
関数は、文字列str
の各文字を順番にstream
に書き込みます。
例
#include <stdio.h>
int main() {
FILE *fp;
fp = fopen("test.txt", "w");
if (fp == NULL) {
perror("fopen failed");
exit(1);
}
fputs("Hello, world!\n", fp);
fclose(fp);
return 0;
}
この例では、fputs
関数は "Hello, world!" という文字列を "test.txt" というファイルに出力します。
- ファイル入出力に関する詳細については、C言語の標準ライブラリのマニュアルを参照してください。
- より複雑なファイル入出力操作には、
fprintf
関数やfwrite
関数などの他の関数を使用することが推奨されます。 fputs
関数は、比較的単純なファイル出力タスクに使用されます。
fputs 関数の利点
- 改行 (
\n
) 文字を自動的に追加しない(テキストモードの場合) - NULL 文字 (
\0
) を自動的に処理する - シンプルで使いやすい
fputs 関数の欠点
- エラー処理が限定的
- フォーマットされた出力には対応していない
- バイナリモードでの使用には適していない
- より高度なファイル入出力操作が必要な場合は、
fopen
、fclose
、fread
、fseek
などの他のファイル入出力関数と組み合わせて使用します。 - バイナリデータを書き込む必要がある場合は、
fwrite
関数を使用します。 - フォーマットされた出力を必要とする場合は、
fprintf
関数を使用します。
ファイルへの単純な文字列出力
#include <stdio.h>
int main() {
FILE *fp;
fp = fopen("test.txt", "w");
if (fp == NULL) {
perror("fopen failed");
exit(1);
}
fputs("Hello, world!\n", fp);
fputs("This is another line.\n", fp);
fclose(fp);
return 0;
}
このコードは、"test.txt" というファイルに "Hello, world!" と "This is another line." という 2 つの行を出力します。
エラー処理
#include <stdio.h>
int main() {
FILE *fp;
fp = fopen("nonexistent.txt", "w");
if (fp == NULL) {
perror("fopen failed");
exit(1);
}
fputs("This will not be written.\n", fp);
fclose(fp);
return 0;
}
このコードは、存在しないファイル "nonexistent.txt" を開こうとします。ファイルが開けないため、fopen
関数は NULL
を返し、perror
関数はエラーメッセージを出力します。
バイナリモードでの使用
#include <stdio.h>
int main() {
FILE *fp;
char data[] = {0x61, 0x62, 0x63, 0x64, 0x65};
fp = fopen("binary.data", "wb");
if (fp == NULL) {
perror("fopen failed");
exit(1);
}
fputs("This will not be written correctly.\n", fp); // エラーが発生する
fwrite(data, sizeof(data), 1, fp);
fclose(fp);
return 0;
}
このコードは、"binary.data" というバイナリファイルを開き、data
配列の内容を書き込みます。しかし、fputs
関数はテキストモードで動作するため、バイナリデータとして正しく書き込まれません。バイナリデータを書き込むには、fwrite
関数を使用する必要があります。
#include <stdio.h>
int main() {
FILE *fp;
fp = fopen("test.txt", "w");
if (fp == NULL) {
perror("fopen failed");
exit(1);
}
fputs("Hello, %s!\n", fp); // フォーマットを使用できない
fprintf(fp, "Goodbye, %s!\n", "world"); // フォーマットを使用できる
fclose(fp);
return 0;
}
以下に、いくつかの代替手段とその利点と欠点を示します。
fprintf 関数
- 欠点:
fputs
関数よりも少し複雑- NULL 文字 (
\0
) を自動的に処理しない
- 利点:
- フォーマットされた文字列出力が可能
- 変数や式を文字列に埋め込むことができる
- エラー処理が容易
例
#include <stdio.h>
int main() {
FILE *fp;
int age = 25;
fp = fopen("test.txt", "w");
if (fp == NULL) {
perror("fopen failed");
exit(1);
}
fprintf(fp, "Hello, world! I am %d years old.\n", age);
fclose(fp);
return 0;
}
fwrite 関数
- 欠点:
- 文字列データの書き込みには
fputs
やfprintf
関数よりも複雑 - フォーマットされた出力には対応していない
- 文字列データの書き込みには
- 利点:
- バイナリデータの書き込みに適している
- 構造体や配列などの複雑なデータを書き込むことができる
例
#include <stdio.h>
int main() {
FILE *fp;
struct person {
char name[32];
int age;
};
struct person p = {"Alice", 30};
fp = fopen("data.bin", "wb");
if (fp == NULL) {
perror("fopen failed");
exit(1);
}
fwrite(&p, sizeof(struct person), 1, fp);
fclose(fp);
return 0;
}
fopen
、fclose
、fread
、fseek
などの関数を使用して、より高度なファイル入出力操作を組み立てることができます。
fputs
関数は、フォーマットされた出力には対応していません。フォーマットされた出力を必要とする場合は、fprintf
関数を使用してください。fputs
関数は、NULL 文字 (\0
) を自動的に処理します。文字列に NULL 文字を含める必要がある場合は、fprintf
関数またはfwrite
関数を使用する必要があります。fputs
関数は、テキストモードで開かれているファイルにのみ使用してください。バイナリモードで開かれているファイルにfputs
関数を使用すると、予期しない結果が生じる可能性があります。