読者です 読者をやめる 読者になる 読者になる

C言語 ファイル入出力

Program C言語

C言語改訂版1 はじめてのプログラミング (CD-ROM付) (プログラミング学習シリーズ)

C言語改訂版1 はじめてのプログラミング (CD-ROM付) (プログラミング学習シリーズ)

新規ファイルの作成(ファイルへの出力)は、

1. ファイルポインタ(FP)を宣言する   FILE * ファイルポインタ名

2. ファイルを開く fopen(オープンするファイル名, オープンモード) ⇒ 返り値はFP。オープンモードとは、ファイルをオープンするときに読み(r)/書き(w)を指定

3. 文字列を出力する fputs(出力する文字列, FP)

4. ファイルを閉じる fclose(FP)

 

ファイルの読み込みは、

fgets()関数で一行ずつ読み込む。これをfor文で繰り返す。配列オーバー防止のため、最大読込長をしてしておく。

 

実際にやってみよう。まずはファイルへの出力から。さっきのコードを、アウトプットをファイルに書き込み保存する形に変えてみる。

#include <stdio.h>
#include <string.h> 	//strcat()を使うため
#include "Person.h"	//さっきのコードを参照

main  () {
	int i = 0;
	char output[1000];  //出力用変数
	char line[200];    //出力用変数

	struct Person A[3] = {
		{1, 19801203, "Tokyo", "160-0012", "Male", "Tanaka Taro", 600},
		{2, 19830228, "Kyoto", "606-8243", "Female", "Sato Hanako", 1000},
		{3, 19480831, "Chiba", "277-0291", "Male", "Takahashi Jiro", 800},
	};

	struct Person *p;
	p = A;
	FILE *fp;		//ファイルポインタの定義

	//出力のヘッダーをoutputに代入
	sprintf(output, "ID\tBrithday\tPref\tPostalcode\tSex\tName\t\tIncome\n"); 

	for(i = 0; i < 3; i++) {
		//出力を一行ずつlineに代入
		sprintf(line, "%d\t%d\t%s\t%s\t%s\t%s\t%d\n",
			(p+i)->ID, (p+i)->birthday, (p+i)->pref, (p+i)->postalcode,
			(p+i)->sex,(p+i)->name, (p+i)->income);

		//lineをoutputに追記する
		strcat(output, line);
	}
	fp = fopen("output.txt","w");	//ファイルを書き込みモード(w)で開く
	fputs(output, fp);		//outputを書き込む
	fclose(fp);			//ファイルを閉じる
	return 0;
}

 同フォルダに、output.txtというファイルが出力される。開いてみると…

ID	Brithday	Pref	Postalcode	Sex	Name		Income
1	19801203	Tokyo	160-0012	Male	Tanaka Taro	600
2	19830228	Kyoto	606-8243	Female	Sato Hanako	1000
3	19480831	Chiba	277-0291	Male	Takahashi Jiro	800

となっている。ファイルの出力場所を指定する際は、\の代わりに\\を用いる必要がある。

      C:\\cygwin\\home\\Nakhirot

という具合に書く。

 

次にファイルからの読み込み。今出力したファイル(output.txt)を読み込む。

#include <stdio.h>
#include <string.h>	//strcat()を使うため
#include "Person.h"	//さっきのコードを参照

main  () {
	FILE *fp;		//1.ファイルポインタ
	char *p;		//1.終了判定のためのポインタ
	char str[600];		//1.ファイル読込用の領域
	char fname[100];	//1.ファイル名格納用文字列
	char input[2400];	//1.読み込んだ行を格納する変数

	puts("Please input a file name.");  //output.txtを入力する
	gets(fname);		//ファイル名をfnameに代入

	fp = fopen(fname, "r");	   //2.読込モードでfnameを開く
	p = fgets(str, 600, fp)    //3.引数は読込用文字列, 最大読込長, ファイルポインタ

	while (p != NULL) {
		printf("%s",str);	//4.読み込んだ行を表示
		strcat(input, str);	//4.読み込んだ行をinputに格納
		p = fgets(str, 600, fp);//4.再び一行読み込む
	}
	fclose(fp);			//5.ファイルを閉じる
}

   1. ファイルポインタと読込用文字列を定義

   2. fopen(ファイル名, "r") で読込モードでファイル開く

   3. 1行ずつ fgets(読込用文字列, 最大読込長, ファイルポインタ) で読み込む

   4. while (p != NULL) により行毎の読込を繰り返す

   5. fclose(fp)によりファイルを閉じる

という流れになる。長すぎる…。もっとシンプルな方法はないのか。

【追記】

出力について、上記ではfputs( )を使用しているが、fprintf( )も使えるらしい。fputsの場合は、fputs(文字列)として出力する。つまり、文字列の部分は前行までに作っておかなくてはならない。一方、fprintf( )を使うと、

     fprintf(fp, "%d\t%d\t%s\t%s\t%s\t%s\t%d\n",a, b, c, d, e, f, g);

書式をカスタマイズして、ファイルポインタfpへ出力することができる。