課題 [10] 文字列(5/9)

問 5(提出プログラム名:ex1005.c)

このプログラム(ex1005.c)をダウンロードし,プログラムが以下の作業を実行できるよう,
その中の関数 convertmask をそれぞれ完成させなさい

【プログラムで行おうとしている作業】
①まず,文字列(途中に空白は含まない)を main 関数で読み込んでそのまま出力する.
②その後,その文字列を別の関数 convert へ渡して
 内容をすべて大文字に変換し,再び main 関数で変換後の内容を出力する.
③最後に,その変換後の文字列を別の関数 mask へ渡して
 3 文字ごとに * (半角のアスタリスク)に書き換え,再び main 関数で書き換え後の内容を出力する.

【補足説明】
以前に説明した通り,関数の引数として配列を渡した場合は特別扱いになり,その配列の内容を関数の中で直接書き換えることができます.
したがって,関数の中で str[i] に何か上書きをすれば,関数呼出しが終わった後でもその変更は有効のままになっています.

【注意】
この問題では関数 main の内容は一切書き換えないこと.
なお,入力される文字列の長さは SIZE 文字未満であると仮定してプログラムを作ってよい(SIZE はマクロとして定義されている).ただし,マクロ定義部分以外で 256 やこれに関係する数字を直接書いてはいけません.

【ヒント】
関数 convertmask を作るにあたって,文字列の末尾までチェックしていく際
  for ( i = 0; i < SIZE; i++ ) {
で繰り返すのは誤りですので注意してください.
この誤りに気が付かず,運悪くナル文字(\0)を別の文字で上書きしてしまうと文字化けの原因になります.
for 文でこれを書くならば,文字列の場合は
  for ( i = 0; str[i] != '\0'; i++ ) {
が正解です.

あとは,この for 文の中で大文字への変換(関数 convert の場合)や '*' の上書き(関数 mask の場合)を行えばよいことになります.
なお, 関数 mask の場合には 3 文字ごとに '*' で上書きすることになりますが,これは配列の添字 i を 3 で割った余り(i % 3)に注目するとよいです.i % 3 の値がいくつの時に '*' を上書きすれば実行例と同じになるかを考えるとよいでしょう.

【ヒント2】
例年,for 文での繰り返しで次のように i += 3 とすることで
3 個飛ばしで置き換えていこうとする人が何人かいます.
  for ( i = 2; str[i] != '\0'; i += 3 )
アイデアそのものは非常に良いのですが,その場合,ナル文字チェック(str[i] != '\0')も
3 個飛ばしでしか行われない
ので,もともとナル文字が書いてあった場所を読み飛ばしてしまう
ことがあり,残念ながらうまく動作しないことがあります(なので評価は「誤り」扱いとなります).

  • 【プログラムの実行結果】(その1)赤字は実行時にキーボードから入力する内容
    ※「一部をマスク」の結果が以下の実行例と本当に同じかよく確認すること
アルファベットのみを使った文字列を入力してください(255文字以下):
amanhirohisaatehimeuniversity
元々の文字列:[amanhirohisaatehimeuniversity]
大文字に変換:[AMANHIROHISAATEHIMEUNIVERSITY]
一部をマスク:[AM*NH*RO*IS*AT*HI*EU*IV*RS*TY]
  • 【プログラムの実行結果】(その2)赤字は実行時にキーボードから入力する内容
アルファベットのみを使った文字列を入力してください(255文字以下):
abc
元々の文字列:[abc]
大文字に変換:[ABC]
一部をマスク:[AB*]
  • 【プログラムの実行結果】(その3)赤字は実行時にキーボードから入力する内容
アルファベットのみを使った文字列を入力してください(255文字以下):
a
元々の文字列:[a]
大文字に変換:[A]
一部をマスク:[A]

【過去にあったミス(実際に減点となり,やり直しを命じられた例)】
実行の画面出力が上の例と違うきちんと確認していない).
 例えば, * の位置が違っている.
■ main 関数の内容を書き変えてしまっている.
インデントに不備がある(VSCode 上でインデントを自動で揃える作業をやっていない).


ミスが無いことを確認したら次の問題へ → [ 問6 (ex1006.h) ]