平成30年 春期 基本情報技術者 午後 問09
問09 C言語次の C プログラムの説明及びプログラムを読んで,設問1,2に答えよ。 簡易集計プログラムである。このプログラムを用いると,例えば,図1の入力ファイルから, 品番ごとのレコード件数と金額の合計を求めて,図2の集計ファイルを得ることができる。 プログラムは,キー項目及び数値項目の,開始桁位置及び桁数を引数で受け取り, キー項目で整列済みのレコードを入力ファイルから読み込み,キー項目の値ごとに, その作数と数値項目の値の合計を求め,集計ファイルにレコードとして書き出す。 ここで,数値項目には整数の値が入る。
図1 入力ファイルのレコード例 図2 集計ファイルのレコード例 〔プログラム1の説明〕 (1) 入力ファイルは,固定長レコードの並びから成る。レコードは, 1,000 文字以下の 1 バイト文字の並びであり,最後の文字の後には改行文字が付いている。 ファイル名は,引数 dataFile で指定する。 (2) レコード中のキー項目の開始桁位置及び桁数は,それぞれ引数 keyPos 及び keyLen で指定する。 また,数値項目の開始桁位置及び桁数は,それぞれ引数 valuePos 及び valueLen で指定する。 開始桁位置は,レコードの先頭文字の桁位置を 0 として数える。キー項目及び数値項目の桁数は, いずれも 9 桁以下とする。 (3) 入力レコードは,キー項目の昇順に整列されている。 (4) 集計ファイルにレコードとして,キー項目の値,キー項目ごとの件数及び数値項目の値の 合計を各 9 桁分の領域に右詰めで出力し,各項目の直前に1個の空白文字を出力する。 レコードの最後の文字の後には改行文字を付ける。ファイル名は, 引数 listFile で指定する。 (5) 引数及び入力レコードの内容に誤りはないものとする。また,数値項目の値の 合計は 9 桁以下であり,算術演算であふれは起きないものとする。 (6)プログラム中で使用しているライブラリ関数(一部)の概要は,次のとおりである。
・fgets(s, m, f ): ストリームf から文字の列(改行文字まで,最大 m − 1 文字)を読み取り, 配列 s に格納し,s を返す。ストリームの終わりに達した場合は NULL を返す。 ・strcmp(s1, s2 ):文字列 s1 と s2 を比較し,s1 < s2 のとき負の値を, s1 =s2 のとき 0 を, s1 >s2 のとき正の値を,それぞれ返す。 ・strcpy(s1, s2 ):文字列 s2 を文字列 s1 に複写する。 ・strncpy(s1, s2, n ):文字列 s2 の先頭から n 個の文字を文字列 s1 に複写し, 文字列 s1 の値を返す。 〔プログラム1〕 #include <stdio.h> #include <stdlib.h> #include <string.h> #define recSize 1ØØ2 /* 入力レコードの最大文字数 + 2('\n', '\Ø') */ void outList(char *dataFile, char *listFile, int keyPos, int keyLen, inl valuePos, int valueLen) { a *inFile, *outFile; char inBuf[recSize], inKey[1Ø], key[1Ø], temp[1Ø]; long count, inValue, value; char format[] = " %9s %9ld %9ld\n"; key[keyLen] = '\Ø'; inKey[keyLen] = '\Ø'; temp[valueLen] = '\Ø' ; outFile = fopen(listFite, "w"); inFile = fopen(dataFile, "r"); if (fgets(inBuf, recSize, inFite) != NULL) { strncpy(key, inBuf + keyPos, keyLen); count = 1; value = atol(strncpy(temp, inBuf + valuePos, valueLen)); while (fgets(inBuf, recSize, inFile) != NULL) { strncpy(inKey, inBuf + keyPos, keyLen); inValue = atol(strncpy(temp, inBuf + valuePos, valueLen)); if (strcmp(key, inKey) != Ø) { fprintf(outFile, format, key, count, value); count = 1; strcpy(key, inKey); value = inValue; } else { b } } c } fclose(inFile); fclose(outFile); }
a に関する解答群 b,c に関する解答群 イ fprintf(outFite, format, key, count, value);
ウ count++:
エ count++;
オ count--;
図3に示す,時分秒のうちの時をキー項目として昇順に整列済みのレコードを 入力ファイルから読み込み,時間帯( 0 時台,1 時台,…,23 時台)ごとの件数と 金額の合計(合計金額)を求め,時,件数,合計金額と合計金額を表す棒グラフを印字する。 この処理を,次の手順で行う。 (1) プログラム1を利用して,図3の入力ファイルから,図4の集計ファイルを得る。 (2) プログラム2を利用して,図4の集計ファイルから,図5の印字結果を得る。
図3 入力ファイルのレコード例 図4 集計ファイルのレコード例
図5 印字結果の例 〔プログラム2の説明〕 (1) プログラム1で書き出した集計ファイルからレコードを読み込む。ファイル名は, 引数 listFile で指定する。 (2) 読み込んだ各レコードに,そのレコードの合計金額の値 value に応じた長さのグラフを 追加して印字する。集計ファイル中の合計金額の値の最大値 valueMax を 25 個の “*”で表し,他の値は,25 × value ÷ valueMax 個(小数点以下切捨て)の“*”で表す。 ここで,集計ファイル中の合計金額の値の最大値は正であり,最小値は 0 以上であるものとする。 〔プログラム2〕 #include <stdio.h> #include <stdlib.h> #define listLen 32 /* 入力レコードの最大文字数 + 2 ('\n', '\Ø') */ void outListG(char *listFile) { a *inFile; char inBuf[listLen]; long value, valueMax; char graph[] = "*************************"; inFile = fopen(listFile, "r"); valueMax = Ø; while (fgets(inBuf, listLen, inFile) != NULL) { value = atol(inBuf + 21); if (value > valueMax) { valueMax = value; } } fclose(inFile); inFile = fopen(listFile, "r"); while (fgets(inBuf, listLen, inFile) != NULL) { value = atol(inBuf + 21) ; printf("%.3Øs l%s\n", inBuf, &graph[25 - 25 * value / valueMax]); /* α */ /* %.3Øs はレコードの先頭からの 3Ø 桁(\n の直前まで) を出力する */ } fclose(inFile); } プログラム2は,作成途中である。図4の集計ファイルを用いると図5の印字結果が 得られるが,集計ファイル中の合計金額の値によっては,コメント /* α */ を 付した印字処理の実行時に問題が発生する場合がある。 〔プログラム2の説明〕の (2) にある前提“集計ファイル中の合計金額の値の 最大値は正であり,最小値は 0 以上である”が満たされない場合も考慮に含め, コメント /* α */ を付した印字処理の実行時に発生し得る事象として, @算術演算であふれが発生,A算術演算でゼロ除算が発生,B配列の定義外の要素位置を参照,がある。 これらの事象が発生し得る value と valueMax の値の例を,表1にまとめた。 ここで,long 型の数値の範囲は,−231〜231 − 1 (231=2,147,483,648)とする。
d 〜 f に関する解答群
[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]
©2004-2024 情報処理試験.jp
|
プライバシーポリシー・著作権・リンク
|
お問合わせ
| ||||