いろんな言語で簡単なプログラムを書いてみるテスト(1)

とりあえずC言語D言語JavaSchemePerlOCamlRubyでcatプログラムを。引数で与えられたファイルを順番に標準出力に出力するやつ。仲間外れ一人。

訂正

コメントにも書きましたけど。本当はPerl以外は本来のcatとは違って、引数無かったときは即終了する子を書こうとしてました。でもDがdinをほげっててほげ。あとまあそれぞれのコードに色々ひどいところがあるのは、せっかくなので残しておきます。いちばんひどいのはRubyの子で、なんと開いたファイルを閉じていません。コメントで気付きました。ありがとうございます。

C

#include <stdio.h>
void cat(FILE *input)
{
  int c;
  while((c=fgetc(input))!=EOF){
    putchar(c);
  }
}
int main(int argc, char *argv[])
{
  if(argc>0){
    int i;
    for(i=1;i<argc;++i){
      FILE *input;
      if((input=fopen(argv[i], "r"))==NULL){
        perror("fopen");
        return 1;
      }
      cat(input);
      fclose(input);
    }
  }
  return 0;
}

D

import std.stream;
import std.cstream;
void cat(Stream input)
{
  char c;
  while((c=input.getc())!=char.init){
    dout.write(c);
  }
}
int main(string[] argv)
{
  if(argv.length == 1){
    cat(din);
  }
  else{
    for(int i=1;i<argv.length;++i){
      try{
        auto input = new BufferedFile(argv[i]);
        cat(input);
        input.close();
      }
      catch(StreamException){
        dout.writeLine("cannot read " ~ argv[i]);
        return 1;
      }
    }
  }
  return 0;
}

Java

import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

class cat{
  public static void main(String[] args)
  {
    if(args.length > 0){
      for(String arg : args){
        try{
          InputStream is = new FileInputStream(arg);
          cat(is);
          is.close();
        }
        catch(FileNotFoundException fe){
          System.err.println("cannot find "+arg);
          System.exit(1);
        }
        catch(IOException ie){
          System.err.println("cannot read "+arg);
          System.exit(1);
        }
      }
    }
  }
  public static void cat(InputStream input) throws IOException
  {
    int c;
    while((c=input.read())!=-1){
      System.out.write(c);
    }
    System.out.flush();
  }
}

Scheme

(define (cat input)
  (letrec
    ((loop
       (lambda (c)
         (cond
           ((eof-object? c) 0)
           (else (write-char c) (loop (read-char input)))))))
    (loop (read-char input))))
(define (main args)
  (letrec
    ((loop
       (lambda (args)
         (cond
           ((null? args) 0)
           (else (call-with-input-file (car args) cat) (loop (cdr args)))))))
    (loop (cdr args))))

Perl

print<>

OCaml

open Pervasives
let cat file =
  let ic = open_in file in
  let rec iter () =
    begin
      try
        output_char stdout (input_char ic);
        iter ()
      with End_of_file ->
        flush stdout;
        close_in ic
    end
  in
  iter ();;
let _ =
  let rec iter n =
    if n = Array.length Sys.argv
    then ()
    else begin (cat Sys.argv.(n)); iter (n + 1) end in
  iter 1;;

Ruby

def cat(name)
  file = File.new(name, "r")
  while(c=file.getc)
    putc c
  end
end
ARGV.each{|f| cat f}

けっこう前に、ほんのちょっと触ったことあるだけだけど、調べつつ上のコード書いてみてRubyちょっといいかもなーと思った。

test