第6週 ファイル処理
INDEX

目標

  • ユーザ定義関数を定義して、それを利用したプログラムが作成できる。

予習・復習

 以下のスライドを利用して、予習と復習をしよう。復習では、自分の理解度を確認するために、実際にプログラムを作成し、意図する結果が得られるか確認しよう。
  1. ファイル

本日の講義・演習予定

  1. ファイルとストリーム
  2. テキストファイルの読み込み・書き込み
  3. コマンドライン引数
  4. バイナリファイルの読み込み・書き込み
  5. 演習問題
  6. 提出課題
内 容
  1. ファイルとストリーム
  2. テキストファイルの読み込み・書き込み
  3. コマンドライン引数
  4. バイナリファイルの読み込み・書き込み

ファイルとストリーム

ファイル

 ファイルの読み書きの対象にはハードディスク、USBメモリ、SDメモリカード、DVD-RWなど、さまざまなメディアがあります。もし、装置ごとにプログラムを作成しなければならないとすると、例えば、DVD-RWならばDVDドライブの制御プログラムから用意しなければなりません。新しいメディアが登場すればそれに対応したプログラムを追加していかなければなりません。これにユーザが作成するプログラムで対応するには無理があります。 では、実際には、この問題にどのようにして対処しているのでしょうか。直接のファイルへの読み書きはオペレーティングシステム(OS)によって制御されています。OSはメディアやリーダー/ライターといった物理的な装置を隠蔽し、異なるメディアへのデータの流れをストリームというオブジェクトに抽象化することで、ユーザーにも容易にファイルの読み書きの操作を記述できるようにしています。

ファイルに対する読み出し/書き込みの手順

FILE STREAM
  1. ファイルストリームを示す変数を宣言する。FILEはファイル入出力に必要なメンバ変数で構成された構造体です。
  2. ファイルに対して情報を読み/書きするために、fopen関数を使ってファイルをオープンします。引数にはファイル名と、読み込み、書き出し、追記などを指定するモード(下表を参照)を指定します。
  3. 読み込みならばfscanffやfgetsなどの関数を、書き出しならばfprintfやfputsなどの関数を利用してファイルの読み込み/書き出しを行います。
  4. ファイルをクローズします。

テキストファイルの書き込み・読み込み

1文字ずつの書き出し(fputc)

file_write.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fp;						//ストリーム
	char filename[64] = "test.txt";		//ファイル名
	char message[10] = "Algorithm";	//書き込む文字列
	int i;

	fp=fopen(filename,"w");
	if(fp == NULL){		//ファイルオープン
		fprintf(stderr, "Can't open %s.\n", filename);	//エラーメッセージ
		return EXIT_FAILURE;	//異常終了する
	}

	for(i=0; i<10; i++)
		fputc(message[i], fp);	// 書き出し

	fclose(fp);	//ファイルクローズ

	return 0;
}

主なファイル入出力関数
fopen関数
形 式FILE* fopen(char* filename, const char* mode)
機 能ファイルfilenameをmodeで示されるモードでオープンする。
戻り値成功:ファイルストリーム 失敗:NULL
fclose関数
形 式int fclose(FILE *fp)
機 能ファイルストリームfpをクローズする。
戻り値成功:0 失敗:EOF
fgetc関数
形 式int fgetc(FILE *fp)
機 能ファイルストリームfpから1文字を読み込む。
戻り値成功:読み込んだ文字 失敗:EOF
fputc関数
形 式int fputc(int c, FILE *fp)
機 能ファイルストリームfpへ1文字cを書き込む。
戻り値成功:書き込んだ文字 失敗:EOF
fgets関数
形 式int fgets(char *s, int n, FILE *fp)
機 能ファイルストリームfpから読み取った1行分の文字列を文字列sへ格納する。改行を含む。ただし、1行の最大文字数はn-1で、文字列sの最後にナル文字(\0)を付加する。
戻り値成功:読み込んだ文字s 失敗:NULL
fputs関数
形 式int fputs(const char *s, FILE *fp)
機 能ファイルストリームfpへ文字列sを書き込む。
戻り値成功:正の値 失敗:EOF
fscanf関数
形 式int fscanf(FILE *fp, const char *format, ...)
機 能ファイルストリームfpから書式付き文字列formatを読み込む。
戻り値成功:読み込んだ項目数 失敗:EOF
fprintf関数
形 式int fprintf(FILE *fp, const char *format, ...)
機 能ファイルストリームfpへ書式format付きの文字列を書き出す。
戻り値成功:書き出した文字数 失敗:負の値

主なテキストファイルのモード一覧
モード説明
r読出し(read)専用モード(ファイルがなければNULLを返す)
w書き込み(write)専用モード(ファイルが存在する場合は上書きする)
a追記(append)専用モード(ファイルの最後に追加、ファイルがなければ新規作成)
r+, w+, a+更新モード(読み書きの両方が可能)

標準入出力ストリーム
 stderr、stdout、stdinはそれぞれ、標準エラー出力、標準出力、標準入力用のストリームです。これらのストリームはプログラムが起動されると同時に自動的にオープンされ、プログラムが終了するときに自動的にクローズされます。関数printfの出力先が標準出力(ディスプレイ)なのはstdoutに固定されているためで、関数scanfの入力元が標準入力(キーボード)なのはstdinに固定されているためです。
     
  • EXIT_FAILURE プログラム終了時に実行環境へ返す値で、「異常終了」を示す。その値は、stdlib.hで定義されている。「正常終了」を示す定数としてEXIT_SUCCESSがある。
  • EOF : End Of File  ファイルの最後を示す。

1文字ずつの読み込み

file_read.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fp;		//ストリーム
	char fname[] = "test.txt";	//ファイル名
	char ch;

	fp = fopen(fname,"r");	//ファイルオープン
	if(fp == NULL){
		fprintf(stderr,"Can't open %s.\n",fname);
		return EXIT_FAILURE;
	}

	while((ch=fgetc(fp)) != EOF){	//EOFになるまで読み込む
		putchar(ch);		//表示
	}
	printf("\n");
	fclose(fp);		//ファイルクローズ

	return 0;
}

1行ずつの書き出し

file_write_line.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fp;						//ストリーム
	char filename[16] = "test.txt";		//ファイル名
	char message[128];
	int result,i=0;

	printf("message>> ");
	fgets(message,10,stdin);	//保存先、読み取り文字数、標準入力

	//ファイルオープン
	fp = fopen(filename, "w");
	if(fp == NULL){						//ファイルポインタがNULL(空)ならば
		fprintf(stderr, "Can't open %s.\n", filename);	//エラーメッセージの出力
		return EXIT_FAILURE;			//呼び出し元に異常終了を知らせる
	}
									
	// 書き出し
	if(fputs(message,fp)==EOF){						//1行書き出し
		fprintf(stderr,"Error: unable to write to output file.\n");	//エラーメッセージの出力
		fclose(fp);
		return EXIT_FAILURE;			//異常終了
	}
	fclose(fp);
	return 0;
}


1行文字列の読み込み

file_read_line.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fp;
	char fname[] = "test.txt";
	char buff[256];

	fp = fopen(fname,"r");	//ファイルオープン
	if(fp == NULL){
		fprintf(stderr,"Can't open %s.\n",fname);
		return EXIT_FAILURE;
	}

	while(fgets(buff, sizeof(buff), fp) != NULL){	//1行読み込み
		fprintf(stdout, "%s", buff);		//標準出力
	}
	printf("\n");
	fclose(fp);

	return 0;
}


書式付き文字列の書き出し

file_writef.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fp;						//ストリーム
	char filename[128] = "test.txt";
	int count;

	fp = fopen(filename, "w");	//ファイルオープン
	if(fp == NULL){
		fprintf(stderr, "Can't open %s.\n", filename);
		return EXIT_FAILURE;				//呼び出し元に異常終了を知らせる
	}
									
	// 書き出し
	count=fprintf(fp,"%d,%s,%f\n",1,"八王子",36.7);	//成功:文字数 失敗:−1
	if(count==-1){
			fprintf(stderr,"Can't open %s.\n",filename);
			fclose(fp);
			return EXIT_FAILURE;			//異常終了
	}
	fclose(fp);	//ファイルクローズ
	return 0;
}

書式付き文字列の読み込み

file_readf.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fp;
	char filename[128] = "test.txt";
	int no;
	char loc[64]="";
	double temp;

	fp = fopen(filename, "r");
	if(fp == NULL){	
		fprintf(stderr, "Can't open %s.\n", filename);
		return EXIT_FAILURE;
	}
									
	fscanf(fp,"%d,%[^,],%lf",&no,loc,&temp);	//^,カンマ以外の文字
	printf("%f\n",temp);
	fprintf(stdout,"%2d: %s %.1f\n",no,loc,temp);

	fclose(fp);
	return 0;
}
fscanfの書式 "%d,%[^,],%lf" について
 読み取り対象のファイルtest.txtにはカンマ(,)で区切られた、整数、文字列、小数点を含む数字がテキスト形式で保存されています。このようなカンマ(,)もしくはタブで区切られたデータからなるファイルをCSV(Comma Separated Values)形式のファイルと呼びます。Excelなど表計算ソフトで取り扱われるファイル形式です。このCSV形式のファイルから文字列をfscanfを使って読み込む場合は、カンマ(,)も文字列として認識されてしまうため書式指定に%sをそのまま利用することはできません。カンマ(,)を含めず読み込むために、カンマ以外の文字を意味する書式指定%[^,]を指定します。

文字列・数値変換

文字列を数値へ変換
atof関数文字列を浮動小数点数型に変換double atof(char *str)
atoi関数文字列を整数型に変換int atoi(char *str)
atol関数文字列を整数型に変換long atol(char *str)

数値を文字列へ変換
itoa関数整数int型nをd進数の文字列に変換char* itoa(int n, char *s, int d)
ltoa関数整数long型nをd進数の文字列に変換char* ltoa(long n, char *s, int d)

演習

 次のプログラムは、ファイルを読み込んで別の新しいファイルに書き出すコピープログラムです。空欄を埋めて完成させなさい。
fcopy.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *org, *cpy;		//コピー元、コピー先
	char org_fname[] = "copy.c";
	char cpy_fname[] = "copy2.c";
	char ch;

	org = fopen(org_fname,"r");
	if(org == [[空欄ア]]){
		fprintf(stderr,"Can't open %s.\n",org_fname);
		return EXIT_FAILURE;
	}
	cpy = [[空欄イ]];
	if(cpy == NULL){
		fprintf(stderr,"Can't open %s.\n",cpy_fname);
		return EXIT_FAILURE;
	}

	while((ch=fgetc([[空欄ウ]])) != EOF){
		[[空欄エ]](ch,cpy);
	}
	printf("\n");

	[[空欄オ]];
	[[空欄カ]];
	
	return 0;
}

コマンドライン引数

 ここまでのプログラム例の中に登場してきたmain関数の引数はすべてvoid型でした。一方、main関数には以下のような2つの引数を書くこともできます。この引数を利用することで、実行時にコマンドラインからのmain関数へ値を引き渡すことができるようになります。
int main(int argc, char *argv[])
argcには引き渡される値の個数が、argvにはargc個分の文字列が格納されています。

コマンドライン引数とmain関数に引き渡された値

 次のサンプルプログラムを実行して、コマンドラインで入力した引数とmain関数に引き渡された値との関係を確認してみましょう。コマンドライン上での実行ファイル名自体が0個目の引数として渡されていることに注意しましょう。
args.c
#include <stdio.h>

int main(int argc, char *argv[])	//引数の個数、引数の文字列
{
	int i;
	
	printf("引数の数 %d", argc);
	
	for(i=0; i<argc; i++)
		printf("%d: %s", i, argv[i]);
		
	return 0;
}
実行例
>args apple orange grape
引数の数 4
0: args
1: apple
2: orange
3: grape

コマンドラインからファイル名を指定しファイルを読み出す例

args_file_read.c
#include <stdio.h>
#include  <stdlib.h>

int main(int argc, char *argv[])		//引数の個数、引数の文字列
{
	FILE *fp;
	char buff[256];
	
	// ファイルオープン 
	fp = fopen(argv[1],"r");		//ファイル名を引数argv[1]で指定
	if(fp == NULL){
		fprintf(stderr,"Can't open %s.\n",argv[1]);
		return EXIT_FAILURE;
	}
	
	// ファイル読み込み 
	while(fscanf(fp, "%s", buff) != EOF){
		fprintf(stdout, "%s", buff);
	}
	puts("");

	// ファイルクローズ
	fclose(fp);
		
	return 0;
}

バイナリファイルの読み込み・書き込み

バイナリファイルとテキストファイル

 ファイルの読み書きにはテキストモードとバイナリモードの2つのモードがあります。テキストモードでは文字、数値、記号などをすべてASCIIやシフトJISなどの文字コードとして保存します。一方、バイナリモードでは、そのままのデータ形式で保存をします。
 例えば整数123は、テキストモードではそれぞれの数字を文字コード00110001b、00110010b、00110011bとしてファイルに保存します。一方、バイナリファイルでは同じ整数123を32bit幅の整数型として扱うならば00000000000000000000000001111011bとして保存します。
※ バイナリエディタでファイルを開くと、保存されているデータをそのままの状態で確認することができます。


バイナリファイルの書き出し

 整数値123をバイナリ型式で保存するプログラム例です。ファイルのオープンモード指定にはバイナリモードでの書き込みを示す"wb"を指定します。書き込みの関数にはfwriteを使います。引数には順に、変数名、変数の型のバイト数、ファイル識別子を指定します。
file_bwrite.c
#include <stdio.h>

int main(void)
{
	FILE *fp;				//ストリーム
	int a = 123;				//書き込むデータ
	char filename[] = "sample.dat";		//ファイル名

	fp = fopen(filename,"wb");			//ファイルオープン
	fwrite(&a, sizeof(int), 1, fp);		//変数a、int型サイズのデータ、1個分を、fpに書き込む
	fclose(fp);

	return 0;
}
sizeof演算子 変数のバイト数を取得する

入出力関数(バイナリモード)
fwrite関数
形 式fwrite(const void *ptr, size_t size, size_t n, FILE *fp)
機 能ptrが示す領域からsizeバイト単位でn個のデータをストリームfpへ書き込む。
戻り値成功:書き込みに成功した個数 失敗:0
fread関数
形 式fread(const void *ptr, size_t size, size_t n, FILE *fp)
機 能ストリームfpからsize単位でn個のデータを読み込み、ptrが示す領域に格納する。
戻り値成功:読み取り個数 失敗:0

ファイルオープンのモード指定(バイナリモード)
モード説明ファイルがある場合ファイルがない場合
rb読み込み専用正常エラー
wb書き込み専用上書き新規作成
ab追加書き込み最後に追加新規作成
rb+読み込み・書き込み正常エラー
wb+書き込み・読み込み上書き新規作成
ab+読み込みと追加書き込み最後に追加新規作成

バイナリファイルの読み込み

 バイナリファイルに保存されているint型整数を1つ読み込むプログラム例です。ファイルのオープンモード指定にはバイナリーモードでの読み込みを示す"rb"を指定します。読み込みの関数にはfwriteを使います。引数には順に、格納先変数名、変数の型のバイト数、データ数、ファイル識別子を指定します。
file_bread.c
#include <stdio.h>

int main(void)
{
	FILE *fp;
	int a;
	char filename[] = "sample.dat";

	if((fp = fopen(filename,"rb")) == NULL){
		printf("Can't open %s.\n", filename);
	}
	else{
		fread(&a, sizeof(int), 1, fp);	//変数aに、int型サイズのデータを、1個分、fpから読み込む
		printf("%d\n",a);
	}
	fclose(fp);

	return 0;
}

配列データをバイナリファイルへ書き出す

 以下は、整数値0から198までの偶数を配列に格納して、その配列をファイルに書き出すプログラム例です。
file_write_array.c
#include <stdio.h>
#define N 100

int main(void)
{
	FILE *fp;
	char filename[] = "sample.dat";
	int m[N];
	int i;

	for(i=0; i<N; i++) m[i] = i*2;		//配列に0〜198までの偶数を格納
	
	fp = fopen(filename,"wb");		//ファイルオープン
	fwrite(m, sizeof(int), N, fp);		//配列の書き出し
	fclose(fp);					//ファイルクローズ

	return 0;
}

配列データをバイナリファイルから読み込む

 以下は、(3)でファイルに書き出した0〜198までの偶数の配列データを読み込み、各要素を表示するプログラム例です。
file_read_array.c
#include <stdio.h>
#define N 100

int main(void)
{
	FILE *fp;
	int m[N];
	char filename[]="sample.dat";
	int i;

	if((fp = fopen(filename,"rb")) == NULL){			//ファイルオープン
		printf("Can't open %s.\n", filename);
	}
	fread(m, sizeof(int), N, fp);					//配列として読み込み

	fclose(fp);

	for(i=0; i<N; i++)
		printf("m[%d]=%d\n",i,m[i]);				//配列要素の表示

	return 0;
}

ランダムアクセス

ファイル関連関数

ftell関数
形 式long ftll(FILE *fp)
機 能ストリームの現在のファイル位置指示子の値を取得する。
戻り値成功:ファイル位置表示子の値 失敗:-1
rewind関数
形 式void rewind(FILE *fp)
機 能ファイル位置位置子を、ファイルの先頭に位置する。
戻り値
fseek関数
形 式int fseek(FILE *fp, long offset, int whence)
機 能ストリームfpのファイル指示子をwhenceを基点にoffsetバイト移動させる。whenceには、SEEK_SET(ファイルの先頭)、SEEK_CUR(現在位置),SEEK_END(ファイルの最後)のいずれかを指定
戻り値成功:0 失敗:0以外

ファイル位置表示子の位置の表示
file_point.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fp;				//ストリーム
	char filename[64] = "ku.txt";
	long fsize;

	if((fp=fopen(filename,"r")) == NULL){
		fprintf(stderr, "Can't open %s.\n", filename);
		return EXIT_FAILURE;
	}

	fsize = ftell(fp);		//ファイル表示子をの位置取得
	printf("初期位置 %ld バイト\n",ftell(fp));

	fseek(fp,0,SEEK_END);	//ファイルの最後に移動
	printf("終端移動 %ld バイト\n",ftell(fp));

	rewind(fp);		//ファイルの先頭へ
	printf("リワインド %ld バイト\n",ftell(fp));

	fgetc(fp);	//一文字読み取り
	printf("1文字読取後 %ld バイト\n",ftell(fp));

	fclose(fp);

	return 0;
}

ファイル操作

rename関数
形 式int rename( const char *oldname, const char *newname )
機 能ファイル名、ディレクトリ名の変更
戻り値成功:0 失敗:0以外
remove関数
形 式int remove( const char *filename )
機 能ファイルの削除
戻り値成功:0 失敗:0以外


expand_lessBack to TOP

演習問題

  1. 以下の実行例のように、氏名と電話番号を入力してファイルに書き出す電話帳プログラムを作成しなさい。
    	--- 電話帳プログラム ---
    氏名>> tanaka
    電話番号>> 090-1111-2222
    入力を続けますか?(yes...1/no...0)>> 1
    氏名>> saito
    電話番号>> 080-1212-3535
    入力を続けますか?(yes...1/no...0)>> 0
    

  2. 前問でファイルに保存した電話帳を読み込み、表示するプログラムを作成しなさい。

  3. 次のWebページ http://www.kogakuin.ac.jp/english/about/principles.html のHumankindで始まる文章をテキストファイルku.txtとして保存し、このファイル読み込んで文字数をカウントするプログラムを作成しなさい。

  4. 次のWebページ http://www.kogakuin.ac.jp/english/about/principles.html のHumankindで始まる文章をテキストファイルku.txtとして保存し、このファイル読み込んで半角アルファベット文字kもしくはKが合わせていくつ含まれているか調べるプログラムを作成しなさい。

  5. 次のWebページ http://www.kogakuin.ac.jp/english/about/principles.html のHumankindで始まる文章をテキストファイルku.txtとして保存し、特定の文字を入力してその文字だけを文字'*'に置き換えてファイルkua.txtに書き出すプログラムを作成しなさい。
  6. 1から10000の100個の整数の乱数を発生させてファイルに保存するプログラムを作成しなさい。また、ファイルの内容を確認しなさい。

  7. 1から10000の整数をファイルに書き出します。そのファイルを読み込んで素数だけを表示するプログラムを作成しなさい。

  8. 区間\( 0\leq\theta\leq 2\pi \)における関数\(y = sin(\theta) \)の値を求めてファイルに書き出すプログラムを作成しなさい。保存するデータは区間を等間隔で分けた30点に対する値とします。

  9. 先のプログラムで保存したsin関数のデータを読み込み、その結果を下記の実行例のように横軸sin(θ)、縦軸をθとするグラフを表示するプログラムを作成しなさい。
  10.                     *                     
                        .   *                 
                        .       *             
                        .          *          
                        .             *       
                        .                *    
                        .                  *  
                        .                  *  
                        .                  *  
                        .                  *  
                        .                *    
                        .             *       
                        .          *          
                        .       *             
                        .   *                 
                        *                     
                    *   .                     
                *       .                     
             *          .                     
          *             .                     
       *                .                     
     *                  .                     
     *                  .                     
     *                  .                     
     *                  .                     
       *                .                     
          *             .                     
             *          .                     
                *       .                     
                    *   .                     
                        * 
    

Visual Studio を利用する場合のコマンドライン引数とファイルについて

[新規テキストファイルの追加]
ソリューションエクスプローラーのリソースフォルダを選択し、右ボタンをクリックしプルダウンメニューを表示し、その中から「新規項目の追加」を選び、表示されたダイアログに追加したいファイル名を入力する。

[既存テキストファイルの追加]
ソリューションエクスプローラーのリソースフォルダを選択し、右ボタンをクリックしプルダウンメニューを表示し、その中から「既存項目の追加」を選び、追加したいファイルを選択する。

[コマンドライン引数の設定方法]
  1. 1) ソリューションエクスプローラーで該当するソリューション名を選択する。
  2. 2) メニューから[プロジェクト]->[プロパティ]を選択して、プロパティページを表示する。
  3. 3) 「構成プロパティ」-> 「デバッグ」を選択する。
  4. 4) 「コマンドライン引数」をクリックして、引数を設定する。引数が複数ある場合にはスペース区切って入力します。

演習問題解答

OPEN ANSWER
  1. 回答例 ex6-1.c
  2. code/6/telbook_w.c
  3. 回答例 ex6-2.c
  4. code/6/telbook_r.c
  5. 回答例 ex6-3.c
  6. code/6/kusearch.c
  7. 回答例 ex6-4.c
  8. code/6/randwrite.c
  9. 回答例 ex6-5.c
  10. code/6/primefile.c
  11. 回答例 ex6-6.c
  12. code/6/sine_write.c
  13. 回答例 ex6-7.c
  14. code/6/sine_read.c
expand_lessBack to TOP

確認テスト

本日の提出課題(最終提出課題)

  サイズも価値も異なる財宝がN個あります。この財宝を最大サイズSまでしか入らない箱に価値が最大となるように詰めた時の価値を求めなさい。ただし、箱の最大サイズSは7、財宝の個数Nは5としてそのサイズと価値は以下の表の通りだとして、結果を表示すること。
財宝1財宝2財宝3財宝4財宝5
サイズ36142
価値24135
 2009年1月1日から12月31日までの八王子市の日平均気温が格納されたデータファイルhachioji_t2009.csvを読み込み、月平均気温を求めた結果を別ファイルhachioji_t2009_m.csvに書き出すプログラムkadai6.cを作成しなさい。ただし、以下の要件を満たすこと。
[要件]
  • 指定のデータファイルhachioji_t2009.csvをダウンロードして利用すること。
  • 下記のソースファイルを元にして、データファイルを読み込むための関数read_data、月平均気温をファイルhachioji_t2009m.csvに書き出すための関数write_data、main関数内の読み込んだデータから月平均気温を求める処理を完成させること。
  • 実行結果は下記の実行結果例と同じ結果が得られること。

[実行結果例]
# 月平均気温 #
 1月   4.20 ℃ 
 2月   5.82 ℃ 
 3月   8.17 ℃ 
 4月  13.95 ℃ 
 5月  18.75 ℃ 
 6月  21.49 ℃ 
 7月  25.23 ℃ 
 8月  25.57 ℃ 
 9月  21.69 ℃ 
10月  16.74 ℃ 
11月  11.33 ℃ 
12月   6.38 ℃ 

	

[ソースコード]
#include <stdio.h>

//データ読み込み関数
int read_data(double temp[])  
{
	/*
	*  ここを埋める
	*/
	return EXIT_SUCCESS;
}
//データ書き出し関数
int read_data(double temp[])  
{
	/*
	*  ここを埋める
	*/	
	return EXIT_SUCCESS;
}		
int main(void)
{
	double temp[366], avg[12], sum;
	int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
	int i,j,ndays=0;

	read_data(temp);		//日平均気温の読み込み

	printf("\n# 月平均気温 #\n");
	for(i=0; i<12; i++){
		sum=0;
		/*
		 ここを埋めて月別合計を求める
		 */
		avg[i] = sum/days[i];			//月平均気温
		printf("%2d月 %6.2f ℃ \n",i+1,avg[i]);
	}
	printf("\n");

	write_data(avg);	//月平均気温の書き出し

	return 0;
}
	


  • [提出方法]
    1. ideone.comを利用して作成した課題プログラムのURLをCoursePowerへ提出のこと。
    2. 提出するideone.comの課題プログラムには、実行結果が表示されていること。
    3. プログラムの正当性についてどのようにして検証したか簡単に記すこと。
    4. 詳細はスライド「ideoneの使い方」参照のこと。

  • [評価について]
  • プログラムの内容の評価とは別に以下の要件を満たすことを評価の前提とする。
    1. C言語で記述されていること。
    2. ソースコードファイルのコンパイル結果に、ワーニングやエラーが出力されていないこと。
    3. 所定の実行結果が得られるていること。
    4. ソースコードは、インデントや適当な改行が施された見やすい状態であること。

  • [提出期限]
  • 2023年 7月24日(月)までとする。ただし、以降も受け付けるが、最終締め切りを2023年7月27日(木)とする。