平成26年春期試験午後問題 問9

午前試験免除制度対応!基本情報技術者試験のeラーニング【独習ゼミ】

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

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

〔プログラムの説明〕
 関数 format_text は,印字したときに単語が行末で切れないようにテキストを編集してファイルに出力するプログラムである。
  • テキストに含まれる文字は,次のものである。
    1. 英字 A~Z,a~z
    2. 数字 0~9
    3. 記号 !"#%&'()*+,-./:;<=>?[]^_{|}~
    4. 空白文字
    5. 改行文字
  • 単語は,空白文字及び改行文字を含まない文字列であり,空白文字又は改行文字で区切られている。単語の文字数は 20 以下とする。図1に,テキストに含まれる単語の例を示す。
    pm09_1.gif
  • 改行文字を除き,1行分として印字できる文字数(以下,最大文字数という)をプログラムの引数で与えるが,その値は 40 以上とする。単語の途中で最大文字数を超える場合は,単語の直前に改行文字を出力し,その単語が次の行の先頭に印字されるようにする。
  • テキスト中の空白文字及び改行文字は,そのまま出力する。ただし,連続する空白文字を出力している途中で最大文字数を超える場合は改行文字を出力し,最大文字数を超える分は次の行の先頭から印字されるようにする。
  • 関数 format_text の引数は次のとおりである。ここで,引数の値に誤りはないものとする。
    in_file
    編集前のテキスト(以下,入力テキストという)が格納されているファイル名
    out_file
    編集後のテキスト(以下,出力テキストという)を格納するファイル名
    width
    最大文字数
  • プログラムを実行したときは,図2に示すようになる。
pm09_2.gif
pm09_3.gif

設問1

プログラム中の に入れる正しい答えを,解答群の中から選べ。
a に関する解答群
  • lpos = 0
  • lpos = sp
  • lpos = width
  • lpos++
  • lpos += sp
b に関する解答群
  • '\0'
  • '\n'
  • ' '
  • ch
c に関する解答群
  • sp = 0
  • sp = lpos
  • sp++
  • str[lpos] = ch
  • str[sp++] = ch
d に関する解答群
  • lpos > 0
  • lpos >= width
  • lpos > sp
  • sp > 0
  • (lpos + sp) > 0
  • (lpos + sp) >= width
解答選択欄
  • a:
  • b:
  • c:
  • d:
  • a=
  • b=
  • c=
  • d=

解説

本問のプログラムでは入力テキストから1文字ずつ読み込み、読み込んだ文字によって改行コード、空白文字、それ以外の処理に分岐させています。

aについて〕
[a]を含むif文内の処理は入力テキストから改行コード'\0'を読み込んだ場合の処理で、読み込んだ改行コードを str の末尾に格納して出力しています。問題文中の例では、入力テキストの改行コードが読み込まれる下記の5か所でこの改行処理が行われます。
pm09_6.gif
選択肢で処理対象となっている lpos は、出力処理をしている行での出力済み文字数を保持する変数です。改行コードが読み込まれると新しい行に移り、行内での位置が行頭に戻るので lpos を0に戻してあげる必要があります。

a=ア:lpos = 0

bについて〕
空白文字' 'を読み込んだ直後の処理で、lpos に sp の値を加算しています。この処理により、現在行の出力文字数 lpos に出力しようとしている str の長さが加算されます。このとき、sp を足した後の文字数が width 以上になっている場合には、読み込んだ空白文字を str に追加すると最大文字数を超えてしまいます。この場合は、「改行文字を出力し,最大文字数を超える分(の空白文字)は次の行の先頭から印字されるようにする」ので、str の末尾に追加する文字は改行コード(\n)になります。

問題文中の例では、下記の2か所でこの改行処理が行われます。
pm09_7.gif
b=イ:'\n'

cについて〕
[b]で str の末尾に改行コードを格納した後、str を出力し(26行目)、それに引き続き読み込んだ空白文字を出力しています(27行目)。str を出力したので、str に格納されている文字数を表す変数 sp を0に初期化する必要があります。str の出力後に sp を初期化しないと同じ文字列が複数回出力されることになってしまいます。

c=ア:sp = 0

dについて〕
英数字・記号を読み込んだときの処理です。「単語の途中で最大文字数を超える場合は,単語の直前に改行文字を出力し,その単語が次の行の先頭に印字されるようにする。」という仕様と、if文内で改行コードを出力していることから、[d]には「単語の途中で最大文字数を超える場合」を判定する式が入ります。改行しなければならないのは、現在行の出力済文字数 lpos と、str の文字数である sp の合計が width を超えるときです。sp は読み込んだ文字を追加する前の str の文字数(追加後の文字数-1)が格納されているので、(lpos + sp) が width 以上という条件が適切となります。

問題文中の例では、下記の1か所でこの改行処理が行われます。
pm09_8.gif
d=カ:(lpos + sp) >= width

設問2

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

 テキストの編集処理のうち,行頭の空白文字に関する処理を変更することになった。これに合わせて関数 format_text に,処理を追加する。ここで,プログラム中のadには正しい答えが入っているものとする。
  • テキストの編集処理の変更内容は,次のとおりである。
    1. 入力テキスト中の1文字以上の連続する空白文字列で,印字したときに行頭に来る部分は出力しない。
    2. 最初に出力する単語の場合,又は行の先頭に来る単語の場合で直前に出力した単語の最後の文字が"."であったときは,単語の直前に空白文字を一つ出力する。
  • 処理を変更したプログラムを実行したときは,図3に示すようになる。
    pm09_4.gif
  • 処理の変更に対応するために,プログラムを表1のとおりに変更する。
pm09_5.gif
e に関する解答群
  • lpos == 0
  • lpos == sp
  • lpos != 0
  • lpos != sp
  • sp == 0
  • sp != 0
f に関する解答群
  • lch = ' '
  • lch = '.'
  • lch = ch
  • str[sp++] = ' '
  • str[sp++] = lch
解答選択欄
  • e:
  • f:
  • e=
  • f=

解説

eについて〕
空白文字の出力はプログラム中の27行目で行われています。
fputc(ch, ofp);
現在位置が行頭のときには空白文字を出力しないようにしたいのですから、現在行の出力文字数を保持する lpos が0以外のときにだけ空白文字を出力すれば良いことになります。よって、if (lpos != 0){ } で上記の空白文字の出力処理を囲んで、条件付出力に変更します。

e=ウ:lpos != 0

fについて〕
行番号34と35の間に追加される処理は、①行頭、②単語の最初の文字、③前行の最後の文字が'.'、という条件を満たすときに単語の先頭に空白文字を追加する処理です。

変更後のプログラムに追加されている変数 lch は1つ前に読み込んだ文字を保持する変数です(lch … last char)。これは、直前に出力した単語の最後の文字が"."であったときを判定するために使用されます。lch には常に単語の最後の文字を保持させておきたいので、単語構成文字(英数字・記号)を読み込んだ際に、その文字で更新しておく必要があります。よって、[f]には lch に ch を代入する処理が入ります。

f=ウ:lch = ch

Pagetop