練習問題
1. 行番号付きのCatコマンドの作成
例題1を改良し,行番号付きで出力する cat
コマンドを作成してください.
クラス名はCat2
としてください.
ただし,例題1と異なり,複数のファイルを指定できるようにしましょう.
この例題でも,引数は必ず与えられるものとしてください.
出力例
$ cat -n Cat2.java
1 import java.io.*;
...途中省略.
23 }
$ java Cat2 Cat2.java Cat.java
1 import java.io.*;
...途中省略.
23 }
1 import java.io.*;
...途中省略.
19 }
2. Grepコマンドの作成
ここでは,grep
コマンドを作成しましょう.grep
コマンドとは,
キーワードと1つ以上のファイル名が与えられます.
ファイルの行にキーワードが含まれていれば,その行を出力するコマンドです.
クラス名はGrep
としてください.
結果出力には,以下の出力例のようにファイル名も含めてください.
複数のファイルが与えられたとしても,検索できるようにしましょう.
なお,キーワードは省略されることはなく,ファイルは少なくとも1つは指定されるとして構いません.
文字列にある文字列が含まれているかを確認する
ある文字列(stringA
)に,別の文字列(stringB
)が含まれているかを
確認するには,contains
メソッドを利用してください.
String stringA = "this is a pen";
String stringB = "is a";
String stringC = "are";
if(stringA.contains(stringB)){
System.out.println("このメッセージは表示される.");
}
if(stringA.contains(stringC)){
System.out.println("このメッセージは表示されない.");
}
出力例
$ grep line Cat.java
String line;
while((line = in.readLine()) != null){
System.out.println(line);
$ java Grep line Cat.java
Cat.java: String line;
Cat.java: while((line = in.readLine()) != null){
Cat.java: System.out.println(line);
$ java Grep class Cat.java Cat2.java
Cat.java: public class Cat{
Cat2.java: public class Cat2{
3. Headコマンドの作成
指定された行数だけファイルの先頭から出力するコマンドhead
を作成しましょう.
コマンドライン引数では,行数とファイル名を受け取ってください.
ただし,ファイル名は省略可能です.ファイル名が省略された場合,標準入力から読み込むようにしてください.
クラス名は Head
としてください.
コマンドライン引数が1つしか与えられなかった時に,標準入力(System.in
)から受け取るようにするには,
次のようなコードで BufferedReader
を構築してください.
標準入力,標準出力については,基礎プログラミング演習IIの講義資料を確認してください.
BufferedReader in;
// コマンドライン引数が1つしか与えられなかった場合.
if(args.length == 1){
in = new BufferedReader(new InputStreamReader(System.in));
}
else{
in = new BufferedReader(new FileReader(args[1]));
}
出力例
$ head -3 Cat.java # Cat.java の先頭3行を出力する.
import java.io.*;
public class Cat{
$ java Head 3 Cat.java # Cat.java の先頭3行を出力する.
import java.io.*;
public class Cat{
$ cat Cat.java | java Head 4 # 入力を標準入力から受け取る
import java.io.*;
public class Cat{
void run(String[] args) throws IOException{
cat Cat.java | java Head 4
とコマンドを実行した時に,標準入力から入力を受け取ることになります.
そうでない場合(ファイルをコマンドライン引数で指定した場合)は, java Head 3 Cat.java
のようなコマンドの入力になります.
4. Teeコマンドの作成
ここでは,tee
コマンドを作成しましょう.tee
コマンドは
標準入力で受け取った文字列を標準出力と,指定されたファイルに出力するコマンドです.
以下の図のように T の形に入力を分配するところから名付けられています.クラス名をTee
としてください.
コマンドライン引数にファイル名を受け取ってください.
また,標準入力から値を受け取るようにしましょう.上記のようにBufferedReader
を
構築した後は,Cat
の時と同じように入力を受け取れば良いです.
入力が終わればnull
が返ってきますので,自動的にループを抜けるようになっています.
出力例
$ cat hoge # hoge というファイルがないことを確認する.
cat: hoge: No such file or directory
$ cat Cat.java | java Tee hoge # 標準出力と hoge に出力する.
import java.io.*;
...途中省略
}
$ cat hoge # hoge の内容を確認する.
import java.io.*;
...途中省略
}
5. カエサル暗号
カエサル暗号(Caesar暗号; シーザー暗号)はアルファベットを$n$文字ずらす暗号化方式です. この$n (0 \leq n \leq 256)$が鍵となります.
例えば,$n=1$の時,"abracadabra"
という文字列はそれぞれ1文字ずれて 'bcsbdbebcsb'
になります
('a'
→ 'b'
,'b'
→ 'c'
,'r'
→ 's'
,...のようにずらしていきます).
クラス名は CaesarCipher
とし,コマンドラインで3つの引数を受け取ってください.
引数は最初から鍵,入力ファイル,出力ファイルとしてください.
ヒント
文字データを扱うように見えますが,Reader/Writer を使うより,InputStream/OutputStream を使う方が良いでしょう.
InputStream/OutputStreamを利用する場合,文字は単なる数値として扱われますので,1バイト読み込み,暗号化処理を行い,1バイト書き出してください. 暗号化処理は単純に読み込んだデータに鍵を足せば良いです. ただし,暗号化の計算結果が 0以上,256未満になるようにしてください. 暗号化の計算結果が負数であった場合は256を足し,256以上であれば,計算結果から256を減算してください (計算した結果の値が1バイトに収まっている必要があります).
出力例
$ java CaesarCipher 10 CaesarCipher.java encrypted # 鍵を10にして暗号化する.
$ cat encrypted
swzy|~*tk?k8sy84Ezlvsm*mvk}}*Mko}k|Mszro|?***# ..... 以降省略
$ java CaesarCipher -10 encrypted plain # 復号(暗号文を元の文に戻す)する.
$ diff CaesarCipher.java plain # 全く同じはずなので,何も出力されない.
$