こんにちは、もがちゃんです
C言語でテキストファイルへ出力する際に、fputsと同じようによく利用するのがfprintf関数です
fprintf関数は、ファイルへの出力時に利用されるので
fopen関数、fclose関数と一緒に使用します
この記事では
fprintf関数の使い方を簡単なサンプルソースとともに説明します
目次
fprintfの構文
#include <stdio.h>
int fprintf(FILE * restrict stream, const char * restrict format, …);
fprintfの説明
fprintfは、printfの出力先が指定できるように拡張したバージョン
出力先は、streamで指定します
streamに標準出力(stdout)を指定すれば、printfと同じ動作になる
fprintf関数は、formatが指す文字列(書式)の制御に従って、streamが指すストリームへ書き込む。formatは、それに続く実引数の、出力の際の変換方法を指定する。書式に対して実引数が不足しているときの動作は、未定義とする。実引数が残っているにもかかわらず書式が尽きてしまう場合、余分の実引数は、評価するだけで無視する。fprintf関数は、書式文字列の終わりに達したときに呼出し元に復帰する。
JISX3010 プログラム言語C
出力したいファイルに紐づくファイルポインタを指定します
(fopen関数の返却値を指定します)
formatが指す文字列(書式)は、通常の文字列と変換指定文字列から構成されます
ファイルへの出力に
成功した場合は、出力された文字数を返します
失敗した場合は、負の値を返します
fprintf関数は、書き出された文字数を返す。出力エラー又は表現形式エラーが発生した場合、負の値を返す。
JISX3010 プログラム言語C
fprintfの使い方サンプル
フラグとフィールド幅の使い方サンプル
#include <stdio.h>
int main(int argc, char *argv[]) {
char sval[] ="abcde";
int ival = 1234;
double dval = 0.123;
FILE *fp = NULL;
fp = fopen("test.txt","w");
if(fp == NULL) {
// fopen失敗
// streamにstdout指定なので実質printfと同じ
fprintf(stdout, "fopen error fp[%p]\n", fp);
return -1;
}
/*------ 変換指定文字列なし ------*/
fprintf(fp, "hello world\n\n");
/*------ 変換指定文字列あり ------*/
fprintf(fp, "flag1_1:[%-10d]\n", -1 * ival);
fprintf(fp, "flag1_2:[%-10d]\n", ival);
fprintf(fp, "flag1_3:[%-10s]\n", sval);
fprintf(fp, "flag1_4:[%-4s]\n", sval);
fprintf(fp, "\n");
fprintf(fp, "flag2_1:[%+10d]\n", -1 * ival);
fprintf(fp, "flag2_2:[%+10d]\n", ival);
fprintf(fp, "\n");
fprintf(fp, "flag3_1:[% 10d]\n", -1 * ival);
fprintf(fp, "flag3_2:[% 10d]\n", ival);
fprintf(fp, "flag3_4:[% 4d]\n", -1 * ival);
fprintf(fp, "flag3_5:[% 4d]\n", ival);
fprintf(fp, "\n");
fprintf(fp, "flag4_1:[%#10o]\n", ival);
fprintf(fp, "flag4_2:[%#10x]\n", ival);
fprintf(fp, "flag4_3:[%#10f]\n", dval);
fprintf(fp, "flag4_4:[%#10e]\n", dval);
fprintf(fp, "flag4_5:[%#10a]\n", dval);
fprintf(fp, "flag4_6:[%#10g]\n", dval);
fprintf(fp, "\n");
fprintf(fp, "flag5_1:[%010d]\n", -1 * ival);
fprintf(fp, "flag5_2:[%010d]\n", ival);
if(fclose(fp) != 0) {
fprintf(stdout, "fclose error\n");
}
}

変換指定子(i,d,x,X,f,F,e,E,g,G,a,A)の使い方サンプル
#include <stdio.h>
int main(int argc, char *argv[]) {
int ival = 250;
double dval = 0.0123456789;
FILE *fp = NULL;
fp = fopen("test.txt","w");
if(fp == NULL) {
// fopen失敗
// streamにstdout指定なので実質printfと同じ
fprintf(stdout, "fopen error fp[%p]\n", fp);
return -1;
}
/*------ i,d,x,X,f,F,e,E,g,G,a,A ------*/
fprintf(fp, "%%i:[%i]\n", ival);
fprintf(fp, "%%d:[%d]\n", ival);
fprintf(fp, "\n");
fprintf(fp, "%%x:[%x]\n", ival);
fprintf(fp, "%%X:[%X]\n", ival);
fprintf(fp, "\n");
fprintf(fp, "%%f:[%f]\n", dval);
fprintf(fp, "%%F:[%F]\n", dval);
fprintf(fp, "\n");
fprintf(fp, "%%e:[%e]\n", dval);
fprintf(fp, "%%E:[%E]\n", dval);
fprintf(fp, "\n");
fprintf(fp, "%%g:[%g]\n", dval);
fprintf(fp, "%%G:[%G]\n", dval);
fprintf(fp, "\n");
fprintf(fp, "%%a:[%a]\n", dval);
fprintf(fp, "%%A:[%A]\n", dval);
if(fclose(fp) != 0) {
fprintf(stdout, "fclose error\n");
}
}

変換指定子(c,p,n)の使い方サンプル
#include <stdio.h>
int main(int argc, char *argv[]) {
char sval[] = "abcde";
int ival = 'c';
int nval = 0;
void* vval = (void*)sval;
FILE *fp = NULL;
fp = fopen("test.txt","w");
if(fp == NULL) {
// fopen失敗
// streamにstdout指定なので実質printfと同じ
fprintf(stdout, "fopen error fp[%p]\n", fp);
return -1;
}
/*------ c,p,n ------*/
fprintf(fp, "%%c :[%c]\n", ival);
fprintf(fp, "%%p :[%p]\n", vval);
fprintf(fp, "%%n :[%n", &nval);
fprintf(fp, "%d]\n", nval);
if(fclose(fp) != 0) {
fprintf(stdout, "fclose error\n");
}
}

フィールド幅と精度の使い方サンプル
#include <stdio.h>
int main(int argc, char *argv[]) {
char sval[] = "abcde";
int ival = 2500;
double dval = 0.012345;
FILE *fp = NULL;
fp = fopen("test.txt","w");
if(fp == NULL) {
// fopen失敗
// streamにstdout指定なので実質printfと同じ
fprintf(stdout, "fopen error fp[%p]\n", fp);
return -1;
}
/*------ 精度のみ ------*/
fprintf(fp, "%%.3s :[%.3s]\n", sval);
fprintf(fp, "%%.10s:[%.10s]\n", sval);
fprintf(fp, "\n");
fprintf(fp, "%%.3d :[%.3d]\n", ival);
fprintf(fp, "%%.10d:[%.10d]\n", ival);
fprintf(fp, "\n");
fprintf(fp, "%%.3f :[%.3f]\n", dval);
fprintf(fp, "%%.10f:[%.10f]\n", dval);
fprintf(fp, "\n");
fprintf(fp, "%%.3e :[%.3e]\n", dval);
fprintf(fp, "%%.10e:[%.10e]\n", dval);
fprintf(fp, "\n");
/*------ フィールド幅と精度 ------*/
fprintf(fp, "%%13.3s :[%13.3s]\n", sval);
fprintf(fp, "%%13.10s:[%13.10s]\n", sval);
fprintf(fp, "\n");
fprintf(fp, "%%13.3d :[%13.3d]\n", ival);
fprintf(fp, "%%13.10d:[%13.10d]\n", ival);
fprintf(fp, "\n");
fprintf(fp, "%%13.3f :[%13.3f]\n", dval);
fprintf(fp, "%%13.10f:[%13.10f]\n", dval);
fprintf(fp, "\n");
fprintf(fp, "%%17.3e :[%17.3e]\n", dval);
fprintf(fp, "%%17.10e:[%17.10e]\n", dval);
if(fclose(fp) != 0) {
fprintf(stdout, "fclose error\n");
}
}

長さ修飾子の使い方サンプル
#include <stdio.h>
int main(int argc, char *argv[]) {
long long int llval = -1LL;
FILE *fp = NULL;
fp = fopen("test.txt","w");
if(fp == NULL) {
// fopen失敗
// streamにstdout指定なので実質printfと同じ
fprintf(stdout, "fopen error fp[%p]\n", fp);
return -1;
}
/*------ 長さ修飾子 ------*/
fprintf(fp, "%%hhx :[%hhx]\n", (char)llval);
fprintf(fp, "%%x :[%x]\n", (char)llval);
fprintf(fp, "%%hx :[%hx]\n", (short)llval);
fprintf(fp, "%%x :[%x]\n", (short)llval);
fprintf(fp, "%%llx :[%llx]\n", llval);
fprintf(fp, "%%x :[%x]\n", (unsigned int)llval);
fprintf(fp, "\n");
fprintf(fp, "%%hhd :[%hhd]\n%%hd :[%hd]\n%%ld :[%ld]\n",
(char)llval, (short)llval, (long)llval);
if(fclose(fp) != 0) {
fprintf(stdout, "fclose error\n");
}
}

fprintfのまとめ
fprintf関数は、fopen関数、fclose関数とセットで使用する
streamに標準出力(stdout)を指定すると、printf関数と同じ動作をする
printf関数は使用しないで、fprintf関数を使用しておくと、出力先を後で簡単に変更できるようになるのでprintf関数を使用するならfprintf関数の方がオススメ!