基本情報技術者試験の過去問と解説
[TOP] [午前分野別] [午後分野別] [キーワード索引] [令和元年秋午前] [令和元年秋午後]

平成26年 秋期 基本情報技術者 午後 問09
問09   C言語

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

 B社では,セキュリティ管理のために,システムファイルから定期的に, システムの運用・保守用の利用者 ID 一覧を作成し,ファイルで保管している。
 これらの利用者 ID に付加できる特権には,システムファイルの更新などができる システム特権(以下,特権 S という)及びバックアップ作業などのために全ての ファイルを参照できるオペレーション特権(以下,特権 0 という)の2種類がある。
 B社では,セキュリティ管理強化の一環で,利用者 ID の追加・削除や特権の付加・解除が, 申請に基づいて正しくシステムに反映されているかどうかを検証することになった。 そのために,最新及び1世代前の利用者 ID 一覧を比較して,この間の利用者 ID 及び 特権の登録内容の差異を印字するプログラムを作成する。

〔プログラムの説明〕

(1) 最新の利用者 ID 一覧をファイル NewFile から,1世代前の利用者 ID 一覧を ファイル OldFile から,それぞれ読み込む。レコードは利用者 ID の昇順に整列されている。

(2) 1レコードは,利用者 ID (1〜8桁),利用者名(1〜 10 桁),属性(1桁)及び 最終使用日(8桁)の4項目から成る。各項目は,空白文字で区切られている。

@ 利用者 ID 及び利用者名は,英数字から成る文字列である。

A 属性は,次に示す内容の8ビット長のビット列 である。

上位4ビット: 固定値 0100

ビット s : 特権 S が付加されていれば 1,付加されていなければ 0

ビット o : 特権 0 が付加されていれば 1,付加されていなければ 0

ビット g 及び r : その他の属性

B 最終使用日は,数字から成る文字列で,その利用者 ID で最後にログインした 年月日を表す。登録後,一度もログインしていない場合は,全桁が“0”である。

(3) 利用者 ID 及び特権の登録内容の差異は,次のように印字する。

@ NewFile 中にあって OldFile 中にない利用者 ID の場合

 利用者 ID,利用者名の後に“利用者 ID 追加”と印字する。この利用者 ID に 特権 S が付加されていれば“特権 S 付加”,特権 0 が付加されていれば“特権 0 付加” 追加印字する。

A OldFile 中にあって NewFile 中にない利用者 ID の場合

 利用者 ID ,利用者名の後に“利用者 ID 削除”と印字する。この利用者 ID に 特権 S が付加されていれば“特権 S 解除”,特権 0 が付加されていれば“特権 0 解除”を 追加印字する。

B NewFile 及び OldFile の両方にあり,特権 S と特権 0 の少なくとも一方の付加状況が 変わった利用者 ID の場合

 利用者 ID ,利用者名の後に“特権 S 付加”,“特権 S 解除”, “特権 0 付加”,“特権 0 解除”の該当する全てを印字する。

(4) 入力ファイル NewFile 及び OldFile のデータ例を図1に,図1のデータ例を 用いた実行結果を図2に,それぞれ示す。

図1 入力ファイル NewFile 及び OldFile のデータ例

図2 図1のデータ例を用いた実行結果

(5) ライブラリ関数 strcmp(s1,s2) は,文字列 s1 と s2 を比較し, s1 < s2 のとき負の値を,s1 = s2 のとき 0 を,s1 > s2 のとき正の値を, それぞれ返す。

[プログラム]

#include <stdio.h>
#include <string.h>

#define  BitS  ØxØ8
#define  BitO  ØxØ4
#define  BitR  ØxØ1

FILE         *NewFile,   *OldFile;
int           NewEof,     OldEof;
char          NewID[9],   OldID[9];
char          NewName[11],OldName[11];
unsigned char NewAttr,    OldAttr;
char          NewDate[9], OldDate[9];

void ReadNewRecord() {

   fscanf(NewFile, "%s %s %c %s", NewID, NewName, &NewAttr, NewDate);
   if (feof(NewFile) != Ø) {
       NewEof = EOF;                /* EOF:  負の整数定数 */
       strcpy(NewID, "\xFF");       /* \xFF: 8ビット符号の最大値 */
   }
}

void ReadOldRecord() {

   fscanf(OldFile, "%s %s %c %s", OldID, OldName, &OldAttr, OldDate);
   if (feof(OldFile) != Ø) {
      OldEof = EOF;
      strcpy(OldID, "\xFF");
   }
}

void main() {

   NewFile = fopen("NewFile", "rb");
   OldFile = fopen("OldFile", "rb");
   NewEof = Ø;
   OldEof = Ø;
   ReadNewRecord();
   ReadOldRecord();

設問1 プログラム中の に入れる正しい答えを, 解答群の中から選べ。

a に関する解答群

ア (NewEof != EOF) && (OldEof != EOF)

イ (NewEof != EOF) || (OldEof != EOF)

ウ NewEof != OldEof

エ NewEof == OldEof

b に関する解答群

ア ((NewAttr & OldAttr) & (BitS + BitO)) != ØxØØ

イ ((NewAttr | OldAttr) & (BitS + BitO)) != ØxØØ

ウ (NewAttr & (BitS + BitO)) != (OldAttr & (BitS + BitO))

エ (NewAttr l (BitS + BitO)) != (OldAttr | (BitS + BitO))

c に関する解答群

ア ReadNewRecord();

イ ReadNewRecord();
  ReadOldRecord();

ウ ReadOldRecord();

d に関する解答群

ア (NewAttr & (BitS + BitO)) != ØxØØ      イ NewAttr > OldAttr

ウ strcmp(NewID, OldID) < Ø           エ strcmp(NewID, OldID) > Ø

解答 a ←クリックすると正解が表示されます

解答 b ←クリックすると正解が表示されます

解答 c ←クリックすると正解が表示されます

解答 d ←クリックすると正解が表示されます

設問2 次の記述中の に入れる正しい答えを, 解答群の中から選べ。

 利用者 ID が有効に使用されているかどうかを検証するために,一定期間未使用, 又は現在使用不可の利用者 ID 一覧を印字するプログラムを作成する。

(1) 最新の利用者 ID 一覧をファイル NewFile から,一定期間前の世代の利用者 ID 一覧を ファイル OldFile から,それぞれ読み込む。

(2) 次の@,Aの少なくとも一方に該当する利用者 ID について,利用者 ID, 利用者名の後に,@に該当する場合は“現在使用不可”を, Aに該当する場合は“期間中未使用”を印字する。

@ NewFile 中にあって,属性のビット r が1である利用者 ID

 ここで,属性のビット r は,利用者 ID が使用可能なら 0,使用不可なら 1 である。

A NewFile 及び OldFile の両方にあって,最終使用日の値が等しい利用者 ID(全桁が“0”同士で等しい場合を含む)

(3) 図3に,図1のデータ例を用いた実行結果を示す。

図3 図1のデータ例を用いた使用状況の印字結果

 この処理を実装するためには,プログラム中の while 文のブロック内( αで 示した部分)を次のように変更すればよい。ここで, プログラム中の には,正しい答えが入っているものとする。

if (strcmp(NewID, OldID) <= Ø) {
   if (() || () )) {
      printf("\n%-8s  %-1Øs", NewID, NewName);
      if ()
         printf("  現在使用不可");
      if ()
         printf("  期間中未使用");
   }
   ReadNewRecord();
}
else
   ReadOldRecord();

e,f に関する解答群

ア (NewAttr & BitR) != (OldAttr & BitR)

イ (NewAttr & BitR) == BitR

ウ strcmp(NewDate,OldDate) == Ø

エ strcmp(NewID, OldID) == Ø

オ strcmp(NewID, OldID) == Ø && (NewAttr & BitR) == BitR

カ strcmp(NewID, OldID) == Ø && Strcmp(NewDate, OldDate) == Ø

解答 e ←クリックすると正解が表示されます

解答 f ←クリックすると正解が表示されます


[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]