身につくC言語19回目 テキストファイルからの入出力

C言語だけでなく、ほとんどの言語でも他の拡張子と連携をとることができます。

 

一番よくつかわれるのは、拡張子が.txtというテキストファイルです。

 

c言語からテキストファイルを扱うことができると、作業の幅が広がります。

 

例えば、テキストファイルにまとめてある、クラスの番号と名前を番号順に並べ替えたいときなど、いちいち手作業でするのはめんどくさいですよね。

 

そこで、c言語でソートして出力すれば簡単です。(今、エクセルが主流ですが。もちろんエクセルを扱うこともできます。)

 

新しいテキストファイルを作成する

まずは、自分でファイル名を決めて新規作成するところから始めます。


#include<stdio.h>
int main(void)
{
	FILE *fp;
	fp=fopen("hello.txt","w");
	
	if(fp==NULL)
	{
		printf("ファイルを開けません。\n");
		return 1;
	}
	
	fprintf(fp,"hello");
	
	fclose(fp);

	printf("helloと入力しました。\n");
	
	return 0;
}

ファイルを宣言する部分はここです。


FILE *fp;
fp=fopen("hello.txt","w");

FILE *fpというのは、FILEが型のポインタfpを宣言すると言うことです。

 

文字列を出力するときは、char *aとかにしますよね。

 

それで、宣言したfpにファイルを関連づけます。

 

fopen(“hello.txt”,”w”);は、「hello.txtというテキストファイルを書き込みように開け」ということです。

 

“w”で開くと、その階層(この.cファイルがある階層)にhelloという名前のテキストファイルがなければ新規作成をし、すでにhelloというテキストファイルがあれば上書きしなさいということです。

 


if(fp==NULL)
{
	printf("ファイルを開けません。\n");
	return 1;
}

これはもし、ファイルを開くことができなかったときに異常終了させるということです。

 

fp==NULLというのはfpになにもなければという意味です。ファイルが関連づけられていたらfpはNULL以外を示します。

 

return 1というのは、基本的にはreturn 0の動きと変わりはないのですが、コンピュータ的には「0」が正常終了、「0」以外が異常終了を示す事になっていますので1を返します。(一般的には異常終了の場合は「1」か「-1」を返します。

 

開いたファイルに書き込みをするのは


fprintf(fp,"hello");

で行います。

 

printfのまえにfをつけただけです。

 

“hello”の前のfp,というのは、fopenで開いたファイルを指定するということです。

 

最後にfclose(fp);で終わります。

 

重要なのはファイルは開いたら閉じるということです。

 

ファイルをきちんと閉じていないと、他のプログラムで開いているファイルを扱いたいときに「あれ、このファイル閉じられてないぞ?どっかのプログラムが使っているのか」となり開けない場合があります。

 

テキストファイルから読み込む

まずは、読み込むテキストファイルをプログラムと同じ階層に用意してください。


1
2
3
4
5

このようにしましょう。

 

1から5までの整数を書きました。

 

名前は自由ですが、ここでは「kazu.txt」としておきましょう。(windowsならば文字コードはSHIFT-JISでいいです。)

 

とりあえずは、最初の1行の「1」を取り出して出力してみましょう。


#include<stdio.h>
int main(void)
{
	FILE *fp;
	int kazu;
	
	fp=fopen("kazu.txt","r");
	if(fp==NULL)
	{
		printf("開けません。\n");
		return 1;
	}
	
	fscanf(fp,"%d",&kazu);
	
	printf("1行目は%dです。\n",kazu);
	
	fclose(fp);
	
	return 0;
}
	

ここでは


fscanf(fp,"%d",&kazu);

と書いています。

 

これは、「fpを開いて改行があるまでkazuに代入しろ」ということです。

 

kazu.txtでは1のあとに改行があるので、1のみが代入されます。

 

もう一つ大切なのは、


fp=fopen("kazu.txt","r");

というところです。

 

“r”は読み取り専用で開くということです。

 

次はテキストファイルから行ごとに配列に格納していきます。for分を使うことで行ごとに配列に格納していくことができます。


#include<stdio.h>
int main(void)
{
	FILE *fp;
	int kazu[5];
	int i;
	
	fp=fopen("kazu.txt","r");
	if(fp==NULL)
	{
		printf("開けません。\n");
		return 1;
	}
	for(i=0;i<5;i++)
	{
		fscanf(fp,"%d",&kazu[i]);
	}
	for(i=0;i<5;i++)
	{
		printf("%d行目は%dです。\n",i+1,kazu[i]);
	}
	
	fclose(fp);
	
	return 0;
}

演習問題

問題1 次のテキストファイルを作成しなさい。


今日はいい天気ですね。
はい、そうですね。

※テキストの名前は、「hello.txt」とする。

 

問題2 問題1で作成したファイルを読み込んで出力しなさい。

 

演習問題 解答

問題1 解答


#include<stdio.h>
int main(void)
{
	FILE *fp;
	fp=fopen("hello.txt","w");
	if(fp==NULL)
	{
		printf("ファイルを開けません。\n");
		return 1;
	}
	
	fprintf(fp,"今日はいい天気ですね。\n");
	fprintf(fp,"はい、そうですね。\n");
	
	return 0;
}

問題2 解答


#include<stdio.h>
int main(void)
{
	FILE *fp;
	char a[2][30];
	int i,j;
	
	fp=fopen("hello.txt","r");

	
	if(fp==NULL)
	{
		printf("ファイルを開けません。\n");
		return 1;
	}
	
	for(i=0;i<2;i++)
	{
		fscanf(fp,"%s",a[i]);
	}
	for(i=0;i<2;i++)
	{
		printf("%s\n",a[i]);
	}
	
	return 0;
}

これはchar型の大きさ30の配列を2つ用意して、1行目と2行目を格納する方法です。

基本的な入出力は大切なのでしっかりと覚えることが必要でしょう。