システムプログラム 練習問題 #2

練習問題(201)

講義資料の「文字列」の部分で示したプログラムを変更して文字列定数の内容を書き換えると,セグメンテーションフォルトやバスエラーなどの実行時エラーが発生することを確かめよ.

また,cc のオプションに -fwritable-strings を与えると文字列定数の内容の書き換えが可能になることも確かめよ.

練習問題(202)

講義資料の「標準入出力」の部分で示した fgets と puts を用いたプログラムの LINE_LEN を 5 に変えて,コンパイル,実行すると以下の結果になる. どうしてこのような結果になるのか,その理由を調べよ.

$ ./a.out[←]
1234567890[←]
1234
5678
90

abcdefg[←]
abcd
efg

[C-D]
$

練習問題(203)

文字列の中に含まれる単語の数を数える関数 wc を作成しなさい.main 関数からいくつかの文字列を引数に与えて wc 関数を呼び出し,wc 関数が正しく動くことを確かめなさい. 単語は半角空白で区切られているものとするが,区切り文字として使う文字を関数 wc の引数に与えることができるようにしても良い.

練習問題(204)

講義資料の「文字や文字列の検索」の部分で示したプログラムは,先頭に / がある場合や末尾が / で終わる場合をうまく扱えず,実行結果は次のようになる.

$ ./a.out[←]
/dir1/dir2/dir3/file[←]
0:
1: dir1
2: dir2
3: dir3
4: file

dir0/dir1/dir2/[←]
0: dir0
1: dir1
2: dir2
3:

[C-D]
$

最初の例では先頭の / がパスの構成要素と認識され 0: のところに / が出力されるように,また次の例では末尾の / が無視され 3: が出力されないように,プログラムを変更せよ.

練習問題(205)

strlcpy, strdup と同じ動作をする関数 my_strlcpy, my_strdup を作成せよ. main 関数から strlcpy と my_strlcpy の組および strdup と my_strdup の組に同じ引数をいくつかの(2つ以上の)パターンで与えて呼び出し,同じ動作をすることを確かめなさい.

メモリリークを起こさないようにする練習として,malloc や strdup などを用いてヒープ領域に確保したメモリ領域は必ず明示的に free すること.

練習問題(206)

strcmp, strcasecmp と同じ動作をする関数 my_strcmp, my_strcasecmp を作成せよ. main 関数から strcmp と my_strcmp の組および strcasecmp と my_strcasecmp の組に同じ引数をいくつかのパターンで与えて呼び出し,同じ動作をすることを確かめなさい.

練習問題(207)

strlen と同じ動作をする関数 my_strlen1, my_strlen2 を作成せよ. my_strlen1 は単純なプログラムとし,my_strlen2 は工夫されたプログラムとする. my_strlen2 を my_strlen1 よりも20%程度は高速なもの(80%程度以下の実行時間のもの)にしなさい. また,Linux または macOS 付属ライブラリの strlen の実行時間との比較も行いなさい. プログラム部分の実行時間は,その部分の前と後で計時関数(例えば clock 関数や clock_gettime 関数)を呼び出すことによって計測することができる. 有意な差が出るように,1) 少なくとも数 MB 程度の十分に長い文字列を用い,2) その文字列を作成する時間が計測時間に含まれないようにし,3) 同一文字列に対して同じ関数を繰り返し実行すること. my_strlen1 を繰り返し呼び出す部分が少なくとも数秒程度実行されるように,文字列の長さや繰り返しの回数を調節すること.

練習問題(208)

以下のように,シェルのように1行入力を受け取り,コマンド名を表示し,入力のリダイレクション記号「<」があればその記号の後のファイル名を表示し,なければ console と表示するプログラムを作りなさい. 入力行は,コマンド名だけ,または「コマンド名 < ファイル名」(< の前後にスペース1つ)という形式だけであると仮定してよい.

$ ./a.out[←]
command[←]
command name: command
input: console
command < file[←]
command name: command
input: file
$

メモリリークを起こさないようにする練習として,malloc や strdup などを用いてヒープ領域に確保したメモリ領域は必ず明示的に free すること.

練習問題(209)

練習問題(208)のプログラムを変更し,出力のリダイレクション記号「>」およびパイプ記号「|」にも対応できるようにせよ. リダイレクション記号の出現順序としては,「<」の後に「>」が現れるパターンにのみ対応すればよい. また,パイプ記号は1つ現れる場合にのみ対応すればよい. パイプ記号が現れる場合は,パイプ記号の前後のそれぞれのコマンドについて,入出力先が表示されるようにする.

練習問題(210)

練習問題(209)のプログラムを変更し,

  1. リダイレクション記号の出現順序が変わっても対応できるように
  2. 同じリダイレクション記号が複数出てきたらエラーメッセージが出力されるように
  3. スペースがコマンド,リダイレクション記号,ファイル名の周りに入っていなくても,または複数個入っていても,同じように処理できるように
しなさい.

上記の全ての要求を満たしていることを示す実行結果をつけること.