基本情報技術者過去問題 平成30年春期 午後問9

⇄問題文と設問を画面2分割で開く⇱問題PDF

問9 ソフトウェア開発(C)

次のCプログラムの説明及びプログラムを読んで,設問1,2に答えよ。

 簡易集計プログラムである。このプログラムを用いると,例えば,図1の入力ファイルから,品番ごとのレコード件数と金額の合計を求めて,図2の集計ファイルを得ることができる。
 プログラムは,キー項目及び数値項目の,開始桁位置及び桁数を引数で受け取り,キー項目で整列済みのレコードを入力ファイルから読み込み,キー項目の値ごとに,その件数と数値項目の値の合計を求め,集計ファイルにレコードとして書き出す。ここで,数値項目には整数の値が入る。
〔プログラム1の説明〕
  • 入力ファイルは,固定長レコードの並びから成る。レコードは,1,000文字以下の1バイト文字の並びであり,最後の文字の後には改行文字が付いている。ファイル名は,引数 dataFile で指定する。
  • レコード中のキー項目の開始桁位置及び桁数は,それぞれ引数 keyPos 及び keyLen で指定する。また,数値項目の開始桁位置及び桁数は,それぞれ引数 valuePos 及び valueLen で指定する。開始桁位置は,レコードの先頭文字の桁位置を 0 として数える。キー項目及び数値項目の桁数は,いずれも9桁以下とする。
  • 入力レコードは,キー項目の昇順に整列されている。
  • 集計ファイルにレコードとして,キー項目の値,キー項目ごとの件数及び数値項目の値の合計を各9桁分の領域に右詰めで出力し,各項目の直前に1個の空白文字を出力する。レコードの最後の文字の後には改行文字を付ける。ファイル名は,引数 listFile で指定する。
  • 引数及び入力レコードの内容に誤りはないものとする。また,数値項目の値の合計は9桁以下であり,算術演算であふれは起きないものとする。
  • プログラム中で使用しているライブラリ関数(一部)の概要は,次のとおりである。
・atol(s):
文字列 s が表す数値を long 型の表現に変換した値を返す。
・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

プログラム1中の に入れる適切な答えを,解答群の中から選べ。
a に関する解答群
  • char
  • FILE
  • file
  • int
b,c に関する解答群
  • fprintf(outFile,format,inKey,count,inValue);
  • fprintf(outFile,format,key,count,value);
  • count++;
    value += inValue;
  • count++;
    value += inValue;
    fprintf(outFile,format,key,count,value);
  • count--;
    fprintf(outFile,format,inKey,count,inValue)

解答選択欄

  • a:
  • b:
  • c:

解答

  • a=
  • b=
  • c=

解説

以下は〔プログラム1〕の処理部分についてコメントを加えたものです。
pm09_7.png/image-size:488×603

aについて〕
変数 inFile および outFile は、fopen 関数で開いた入力ファイル(dataFile)と集計ファイル(listFile)を格納するために使用されています。C言語では、ファイルを入出力する際にstdio.hに定義されている FILE 構造体へのポインタを使用するので、aには FILE が入ります。

a=イ:FILE

bについて〕
bは、現在読み込んでいるレコードの品番が集計中の品番と同じだったときに行われる処理です。同じ品番の場合には、集計ファイルへの出力は行わず、件数を1件増やすとともに、合計金額に現在読み込んでいるレコードの金額を加算することになります。
集計中の品番のレコード件数は count、集計中の品番の合計金額は value、現在読み込んでいるレコードの金額は inValueに、それぞれ格納されているため、count をインクリメントする処理と、value に inValue を加える処理が入ります。

∴ウ
count++
value += inValue

cについて〕
集計ファイルへの出力のタイミングは次の品番のレコードを読み込んだときなので、次の品番が存在しない最後に集計していた品番については、ファイルの終端に達しても出力が行われません。このためファイルの終端まで達したら、最後に集計していた品番の情報を出力する処理が必要になります。
直前まで集計していた品番のレコード件数は countに、合計金額は value にそれぞれ格納されているので、fprintf 関数でこれらの情報を集計ファイルに出力することになります(※key と inKey はどちらも同じ値になっているはずですので、どちらを出力しても構わないものと思われます。)

∴イ
fprintf(outFile, format, key, count, value)

設問2

次の記述中の に入れる適切な答えを,解答群の中から選べ。ここで,プログラム2中のaには,設問1の正しい答えが入っているものとする。

 図3に示す,時分秒のうちの時をキー項目として昇順に整列済みのレコードを入力ファイルから読み込み,時間帯(0時台,1時台,…,23時台)ごとの件数と金額の合計(合計金額)を求め,時,件数,合計金額と合計金額を表す棒グラフを印字する。この処理を,次の手順で行う。
  • プログラム1を利用して,図3の入力ファイルから,図4の集計ファイルを得る。
  • プログラム2を利用して,図4の集計ファイルから,図5の印字結果を得る。
pm09_3.png/image-size:491×370
〔プログラム2の説明〕
  • プログラム1で書き出した集計ファイルからレコードを読み込む。ファイル名は,引数 listFile で指定する。
  • 読み込んだ各レコードに,そのレコードの合計金額の値 value に応じた長さのグラフを追加して印字する。集計ファイル中の合計金額の値の最大値 valueMax を25個の"*"で表し,他の値は,25×value÷valueMax 個(小数点以下切捨て)の"*"で表す。ここで,集計ファイル中の合計金額の値の最大値は正であり,最小値は 0 以上であるものとする。
pm09_4.png/image-size:475×552
 プログラム2は,作成途中である。図4の集計ファイルを用いると図5の印字結果が得られるが,集計ファイル中の合計金額の値によっては,コメント/* α */を付した印字処理の実行時に問題が発生する場合がある。
 〔プログラム2の説明〕の(2)にある前提"集計ファイル中の合計金額の値の最大値は正であり,最小値は 0 以上である"が満たされない場合も考慮に含め,コメント/* α */を付した印字処理の実行時に発生し得る事象として,①算術演算であふれが発生,②算術演算でゼロ除算が発生,③配列の定義外の要素位置を参照,がある。これらの事象が発生し得る value と valueMax の値の例を,表1にまとめた。ここで,long 型の数値の範囲は,-231~231-1(231=2,147,483,648)とする。
pm09_5.png/image-size:393×117
d,e,f に関する解答群
pm09_6.png/image-size:226×168

解答選択欄

  • d:
  • e:
  • f:

解答

  • d=
  • e=
  • f=

解説

dについて〕
long型の整数の範囲は、およそ-21億~+21憶です。αの式中には「25 * value」がありますが、25に100,000,000を乗じると25億になるのであふれが生じます。

選択肢中で唯一「25 × value」が±21億を超える「カ」が正解です。

∴カ

eについて〕
ゼロ除算とは、0(ゼロ)で割る処理のことで、多くの処理系では処理が中断されたりエラーメッセージが表示されたりします。αの式中には「25 * value / valueMax」がありますが、valueMax が 0 のときにはゼロ除算になります。

選択肢中で唯一 valueMax が 0 になっている「ア」が正解です。

∴ア

fについて〕
各選択肢について「25 - 25 * value / valueMax」を計算することで、範囲外を指定してしまうことなる値の組合せがわかります。※C言語では整数同士の除算の結果は整数(小数点以下切り捨て)になります。
  • ゼロ除算なので処理が中断されます。
  •  25 - 25 * (-10,000,000) / 10,000,000
    =25 - (-250,00,000) / 10,000,000
    =25 - (-25)
    =50

    graphは、0から25(*の数+NULL文字)までのchar配列ですので、50を添え字とした場合、配列の範囲外を指定することになります。よってこれが正解です。
  •  25 - 25 * 0 / 10,000,000
    =25 - 0 / 10,000,000
    =25 - 0
    =25
  •  25 - 25 * 100 / 10,000,000
    =25 - 2,500 / 10,000,000
    =25 - 0
    =25
  •  25 - 25 * 10,000,000 / 10,000,000
    =25 - 250,000,000 / 10,000,000
    =25 - 25
    =0
  • 算術演算中にあふれが発生します。
∴イ

平成30年春期 午後問題一覧

問1 問2 問3 問4 問5 問6 問7 問8 問9 問10 問11 問12 問13 採点講評
© 2010- 基本情報技術者試験ドットコム All Rights Reserved.

Pagetop