練習 [10] 文字列(4/5)

練習 4(提出プログラム名:p1004.c)

サンプルプログラム 4 (sample4.c)p1004.c という別の名前のファイルにコピーしなさい.そして,p1004.c を編集して,次の動作を行うプログラムに仕上げなさい.ただし,この問題では入力される姓や名はすべて小文字であり,それぞれの文字数が 19 を超えることはないものと仮定してプログラムを作ってよい.

【目的の動作】
姓と名で短い方(文字数の少ない方)をすべて大文字で出力し,そうでない方は先頭のみを大文字にして出力する.
なお,姓と名の文字数が同じ場合は,姓の方が短いものと見なして処理せよ.

【注意】
マクロの定義部分以外に 20 (や 19, 18 といった関係する数字)を直接書いてはいけません.
なお,C 言語では文字列の長さ(文字数)を調べるための strlen という関数があらかじめ用意されている(ネットで検索すれば出てくる)が,これを使ってはいけません.ただし,以下のヒントに示すように自前で文字数を調べる関数を作って使うのはOKとする.

【ヒント】
文字列の長さ(文字数)の数え方はサンプルプログラム 3 と同じです.
つまり,先頭から順にナル文字を探していくことで文字列の長さは分かります.
ただ,そのためのプログラムを姓と名について別々に 2 回書くのは少々無駄なので,これを関数としてして作る(文字列を引数とし,その長さを戻り値とする)と以下のようにスッキリと書くことができます:
例えば,
  int get_length( char str[] )
  {
   
サンプルプログラム3を参考に str の文字数を調べる.
   (※文字数カウントに使う変数を 0 で初期化するのを忘れないこと!)
   return str
の文字数;
  }

という関数をあらかじめ(main よりも前で)用意しておけば,目的の処理は main の中で
  if ( get_length(name1) <= get_length(name2) )
  {
   name1 をすべて大文字に置き換える

   name2 は先頭(name2[0])のみ大文字に置き換える
  }
  else

  {
   name2 をすべて大文字に置き換える

   name1 は先頭(name1[0])のみ大文字に置き換える
  }

として書けます.(※「すべて大文字に置き換える」も別の関数として作るとなお良いです)

【ヒント2】すべて大文字へ書き換える関数の作り方.
例えば,引数で与えられた char 配列 str の中身をすべて大文字に書き換えるために
convert_upper という関数を作るとした場合:
  void convert_upper( char str[] )
  {
   int i;
   for ( i = 0; str[i] != '\0'; i++ )
   {
     str[i] を大文字で上書きする
   }
  }
この場合,戻り値は不要(配列の場合は変数の内容を直接書き換えることができるため)ですので,戻り値の型に相当する部分は void で宣言します.

  • 【プログラムの実行例】(その1)赤字は実行時にキーボードから入力する内容
氏名を入力してください(姓と名の間は空白):
aman hirohisa
ようこそ AMAN Hirohisa さん
  • 【プログラムの実行例】(その2)赤字は実行時にキーボードから入力する内容
氏名を入力してください(姓と名の間は空白):
matsuyama taro
ようこそ Matsuyama TARO さん
  • 【プログラムの実行例】(その3)赤字は実行時にキーボードから入力する内容
氏名を入力してください(姓と名の間は空白):
suzuki ichiro
ようこそ SUZUKI Ichiro さん

【過去にあったミス(減点となり,やり直しを命じられる)】
3 種類の実行例を確認せずに提出してしまっている.
 (例1)文字数に関係なく常に姓の方をすべて大文字にしてしまっている.
 (例2)長い方は先頭のみを大文字にすべきところをすべて大文字に変えてしまっている.
ナル文字を別の文字で上書きしてしまい,出力で文字化けしている.
インデントに不備がある(VSCode 上でインデントを自動で揃える作業をやっていない).


ミスが無いことを確認したら次の問題へ → [ 練習5 (p1005.c) ]