画像(logo)

HOME/[C言語 入門]小学生でもわかるC言語3 目次/二日目 ファイルの値を利用する

広告

[C言語 入門 小学生でもわかるC言語3]
二日目 ファイルの値を利用する

広告

↓2016年02月29日発売↓

12歳からはじめる ゼロからのC言語 ゲームプログラミング教室

目次へ戻る

ファイルの値を利用する

今回はファイルから読み出した値を利用してみます。

データファイルなどから値を読み出し利用するのは実用的プログラムにおいては必須の知識ですね!

前回使ったファイル

「test.txt」

画像(ci_2_1)

こちらを再び使いますので内容も画像のように戻しておいてください。

/*二日目 プログラム1*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(){
	int ary_get_c[256];
	int count = 0;
	FILE *fp;

	fp = fopen("test.txt", "r");
	if (fp == NULL){
		printf("ファイルオープン失敗\n");
		exit(1);
	}
	
	while (1){
		ary_get_c[count] = fgetc(fp);
		if (feof(fp)){
			break;
		}
		else{
			count++;
		}
	}

	for(count=0;count<9;count++){
		printf("%c",ary_get_c[count]);
	}

	printf("\n");

	fclose(fp);
	return 0;
}

■実行結果■

画像(ci_2_2)

読み込んだ内容を配列に入れてみました。

実行結果からきちんと配列内にファイルの内容がおさまっているみたいですね!

ちなみに配列内にデータなどを収める時は配列からあふれてしまわないようにけっこう多めに配列を確保しておくなど注意が必要です。

数字と文字コード

ではさっそく取り出した値を利用したいトコロですが、事はそう簡単にはいきません。

さきほどのプログラムの後半、配列の中身を表示した部分

printf("%c",ary_get_c[count]);

この部分の「%c」を「%d」にしてからもう一度実行してみてください。

画像(ci_2_3)

結果が49,50,51...となってしまいました。

するどい方はもうお気づきかと思いますがそうなんです。

文字コードとして表示したから「1〜9」と表示されたのです。

なのでこれを普通の数字「1〜9」と同じように使用するにはここから少しいじらなければいけません。

いくつか方法がありますがここでは単純に「49=1」という関係を考えます。

1,2,3→49,50,51のように並んでいるのでなんとなく想像はつくかと思われますが数字の「0」は「48」になります。

なので単純にそれぞれのデータから「48」を引けば数字の部分が残りそうですね。

/*二日目 プログラム2*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(){
	int ary_get_c[256];
	int count = 0;
	FILE *fp;

	fp = fopen("test.txt", "r");
	if (fp == NULL){
		printf("ファイルオープン失敗\n");
		exit(1);
	}
	
	while (1){
		ary_get_c[count] = fgetc(fp);
		ary_get_c[count] = ary_get_c[count] - 48;
		if (!feof(fp)){
			printf("%d", ary_get_c[count]);
			count++;
		}
		else break;
	}

	printf("\nary_get_c[1] + ary_get_c[3] = %d\n",
		ary_get_c[1] + ary_get_c[3]);

	fclose(fp);
	return 0;
}

■実行結果■

画像(ci_2_4)

無事に数字に変換されたみたいですね!

ary_get_c[count] = ary_get_c[count] - 48;

ここで取り出した内容から「48」を引いて普通の数字に戻してあげております。

ちなみにこの部分を

ary_get_c[count] = ary_get_c[count] - '0';

というように書いても同じ意味になります。

この「'」シングルクォーテーションで囲む事によってそのまま一文字の文字コードを表す事ができます。

広告

2ケタ以上の数字の加工

こんな感じでテキストファイルから数字の部分を拾って利用するには、少しの加工整形をしてやる必要があります。

という事はテキストファイルではないファイル形式というか、保存、読出し形式というかで数字をそのまま保存、読出しする方法も他にあるのですがそれはまた後ほど紹介するとして、今回はもう少しこのテキストファイルからの値の読出し利用方法を見ていきたいと思います。

以下に簡単なデータファイルのようなファイルから値を拾って利用するやり方を紹介いたしますので新しく「test2.txt」というファイルを用意して同じようにソースファイルと同じフォルダに保存してください。

「test2.txt」

画像(ci_2_5)

内容はこんな感じにしてみました。

コンマで区切られたいくつかの2ケタ以上の数字が並んでおります。

これを同じように配列に読み出してみたいと思います。

/*二日目 プログラム3*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(){
	int ary[256] = {0};
	char str[64] = {0};
	char c;
	int ary_count = 0;
	int str_count = 0;
	int i;
	FILE *fp;

	fp = fopen("test2.txt", "r");
	if (fp == NULL){
		printf("ファイルオープン失敗\n");
		exit(1);
	}
	
	while (1){
		c = fgetc(fp);
		str[str_count] = c;

		if(str[str_count] == ',' || str[str_count] == '\n' || str[str_count] == EOF){
			str[str_count] = '\0';
			ary[ary_count] = atoi(str);
			str_count = 0;
			ary_count++;
		}
		else{
			str_count++;
		}

		if(c == EOF)break;
	}

	for(i=0;i<20;i++){
		printf("%d ",ary[i]);
	}

	printf("\n");

	fclose(fp);
	return 0;
}

■実行結果■

画像(ci_2_6)

先ほどのファイルの内容と実行結果を見比べてみるとどうやらうまく読み込めたみたいですね。

では一つ一つみていきましょう。

まず文字列としての数字を通常の数字に変換するのに便利な「atoi()」という関数を使っております。

簡単に使い方を説明すると、ヘッダ「stdlib.h」をインクルードした上で

char str[20] = "123";
int suji = atoi(str);

みたいに使う事ができます。

これで変数「suji」に通常の数字としての「123」が保存される事になります。

もう少し細かくすると

char str[20];
str[0] = '1';
str[1] = '2';
str[2] = '3';
str[3] = '\0';
int suji = atoi(str);

こんな感じです。

文字列の終わりを表す「\0」が必要になります。

このへんの内容が不安な方は小学生でもわかるC言語13日目あたりをご覧になってください。

そして

if(c == EOF)break;

ここにある「EOF」というのはファイルの終わりを表すものになります。

以上を踏まえた上でさきほどのプログラムを辿ってみます。

while (1){
	c = fgetc(fp);
	str[str_count] = c;

	if(str[str_count] == ',' || str[str_count] == '\n' || str[str_count] == EOF){
		str[str_count] = '\0';
		ary[ary_count] = atoi(str);
		str_count = 0;
		ary_count++;
	}
	else{
		str_count++;
	}

	if(c == EOF)break;
}

まず一時的に用意した変数「c」に一文字だけファイルの内容を読み出し、それを配列「str」に保存します。

c = fgetc(fp);
str[str_count] = c;

そしてその一文字を調べます。

if(str[str_count] == ',' || str[str_count] == '\n' || str[str_count] == EOF)

「||」というのは複数の条件を重ねたい時に使います。

これで「もし「,」コンマ、または「\n」改行、または「EOF」ファイルの終わりだったら」という条件になります。

上記のどれにも当てはまらない場合はケタを表す「str_count」をインクリメントして次の文字を再び読み出します。

それでもしそのどれかに当てはまった場合はその前までが数字の部分になるので、「\0」を加えて「atoi()」で数字に変換、配列「ary」に数字として保存しなおします。

後半にファイルが終わりかどうかを判断してループを抜ける処理を書けば完了です。

終端「EOF」の位置

以上のような感じでデータファイルからデータを読み出す事ができます。

少し難しいかもしれませんが、やる事はだいたい決まっておりますのでカタチで覚えてしまうのが良いかと思われます。

しかしながら先ほどのプログラムでは配列をだいぶ多めに取りましたのでよっぽどの事がない限りエラーにはならないと思いますが、もしこれをファイル内のデータ数ぎりぎり(先ほどの場合は15個のデータ)の配列に収めたい場合などは以下の点に気をつける必要があります。

元のデータファイルの終端

まず元のデータファイルですが、特に何も考えずに入力、改行でエンターしてデータを入力していったと思います。

この改行っていうのが曲者になります。

目には見えてないだけでさきほどのプログラムにもある通り改行は「\n」という一文字として立派に存在してます。

なのでデータファイルを入力する時に

画像(ci_2_7)

画像のようなカーソルの位置でピタリと止めればそこがファイルの終端になりますが、ここを改行した場合

画像(ci_2_8)

この場合は改行を一つはさんでの終端になるので、さきほどのプログラムを実行した場合は余分にデータを格納しようとしてバッファオーバーフローの可能性が出てきてしまうのです!

もしこのような場合は元のデータに注意を払う、または読出しプログラムの方で

if(c == EOF || ary_count == 15)break;

あらかじめ配列の限界が来たらループを抜けるというような処理も加えておく事が必要です。

ではファイルからのデータ読出しの基本がわかったトコロで次回はいよいよファイルにデータを書き込んでみたいと思います。

次回

三日目 ファイル書き込み

□ページの先頭へ□

□目次へ戻る□

□HOME□

広告

↓2017年06月16日発売↓

やさしいC 第5版 (「やさしい」シリーズ)

新品価格
¥2,700から
(2017/5/1 13:05時点)

↓2014年08月09日発売↓

新・明解C言語 入門編 (明解シリーズ)

新品価格
¥2,484から
(2017/5/1 13:08時点)

↓2016年02月20日発売↓

新・解きながら学ぶC言語

新品価格
¥2,160から
(2017/5/1 13:10時点)

↓2017年02月11日発売↓

C言語プログラミング基本例題88 88

新品価格
¥3,024から
(2017/5/1 13:12時点)

↓2016年12月15日発売↓

Cの絵本 第2版 C言語が好きになる新しい9つの扉

新品価格
¥1,490から
(2017/5/1 13:13時点)

↓2017年02月08日発売↓

新・明解C言語で学ぶアルゴリズムとデータ構造 (明解シリーズ)

新品価格
¥2,700から
(2017/5/1 13:15時点)