Home > Archives > 2008-01

2008-01

10進数を2進数に変換表示するC言語プログラム

ソースコード

// filename: dtob.c
// convert decimal to binary
#include <stdio.h>

const int BitSize = sizeof(int) * 8; // 整数型のビットサイズを算出
void dtob(int x) {
  int bit = 1, i;
  char c[BitSize];

  for (i = 0; i < BitSize; i++) {
    if (x & bit)
      c[i] = '1';
    else
      c[i] = '0';
    bit <<= 1;
  }
  // 計算結果の表示
  printf("2進数: ");
  for ( i = BitSize - 1; i >= 0; i-- ) {
      putchar(c[i]);
  }
  printf("\n");
}

int main()
{
  int x = 0;
  do {
  printf("10進数を2進数に変換します(0で終了)\n");
  printf("xの値: ");
  scanf("%d", &x);
  dtob(x);
  } while (x != 0);
  return 0;
}

実行結果

[yu@localhost cpp]# gcc dtob.c
[yu@localhost cpp]# ./a.out
10進数を2進数に変換します(0で終了)
xの値: 5
2進数: 00000000000000000000000000000101
10進数を2進数に変換します(0で終了)
xの値: 8
2進数: 00000000000000000000000000001000
10進数を2進数に変換します(0で終了)
xの値: 100
2進数: 00000000000000000000000001100100
10進数を2進数に変換します(0で終了)
xの値: 256
2進数: 00000000000000000000000100000000
10進数を2進数に変換します(0で終了)
xの値: 1984949894
2進数: 01110110010011111110111010000110
10進数を2進数に変換します(0で終了)
xの値: 0
2進数: 00000000000000000000000000000000
[yu@localhost cpp]# 

ビットが0か1の判断するループ順序を逆にして、配列末尾に'\0'を代入すれば、計算結果の表示は配列の文字列表示ですみます。そうすると「計算結果の表示」の際にforループを使う必要はないなぁ、と書き終わった今思いました(ぇー)。

作成の経緯

以前、拡張ハッシュ法の削除関数を実装している際に、キーをバケットに振り分ける際のアドレス算出の処理部分にデバッグプリントが欲しくて作ったものです。

Linuxコマンドで複数ファイルの文字コードを一括変換

Linux系OSのfedora6のデフォルト文字コードはUTF8なので、先日久々に参照したEUCのC++ソースコード中のコメントや出力が文字化けしていました。

そこで、ファイルの文字コードをEUCからUTF8に変換するコマンドを調べたところ、PHPプロ!TIPS+のページの中程にそれに関するコマンドがあったので参考にしました。

$find -name '*.cc' | xargs nkf --overwrite -w

↑は拡張子がccの全てのテキストファイルの文字コードをutf8に変換します。

$find . -type f -print0 | xargs -0 nkf --overwrite -w -Lu

↑このコマンドの意味を簡単に示しますと、まずファイルを検索するfindコマンドで、カレントディレクトリ「.」から通常ファイル「-type f」を探索し出力します「-print0」(常に真)。

% find [検索開始ディレクトリ] (option)
参考:UNIXコマンド [find]

ここで、findコマンドの結果をパイプ「|」をもって渡し、そこでxargsでコマンドを実行します。ここでxargsは以下の機能を持ちます。

xargs[えっくす・あーぐす]
標準入力から引数を読み込み、指定のコマンドを実行するコマンド
参考:UNIXの部屋 検索:xargs (*BSD/Linux/Solaris)

文字コード変換コマンドである nkf のオプション--overwriteは変換した文字コードのデータを元のファイルに上書きするもので、-wが文字コードをUTF8に指定するものです。ちなみに、EUCに変換したい場合は-e、Windowsで使われているSJISにする場合は-sを代わりに指定します。

最後の-Luオプションは改行コードをLFに指定するものです。

Eclipse+CDTを用いてプロジェクトを作成する際の注意点

以前、K-na TechNotes | Homeのページを参考にWindowsでEclipse3.3とCDTをインストールしました。分かりやすく書かれており、とても参考になりました(謝々)。
たまたまK-na TechNotes | CDT のトラブル対策ページ下部にある

<実行>を押しても、デバッグしても、必ず「アプリケーション・エラー 起動に失敗(バイナリ・ファイルがありません)」のメッセージが出ます。

という件を見て、この症状の理由はProject typesの設定ミスではないかと推測しました。

解決方法は、まず上述のページを参照しながら、

  • Cygwin か MinGWをインストール及びパスの設定をする
  • Eclipse(CDT)をインストールする
  • Eclipse上のバイナリパーサの設定等を行う(コンパイルで生成されるバイナリファイルをEclipseで認識させるため)

ここまで出来れば使えるはず。
早速プロジェクトを作成しましょう。

以下の画像はEclipse3.3ですが、Linuxパージョンである。だが、表示項目はWindowsのそれとほとんど変わりません。

[ファイル]>[新規]>[Cプロジェクト]とクリック

Eclipse の C++ プロジェクト作成ウィザード画面

以下の画面で適当なプロジェクト名を打ち込んだ後、Project typesを選択します。ここで[実行可能]>[Empty Project]を選択します。Toochainの項目はLinux系なら[Linux GCC]であるし、上述の設定を行った場合のWindowsのToochainは[Cygwin GCC]を選択します。
これで終了を押せば、問題なくコーディングでき、ビルド→実行となります。

プロジェクトタイプ(Project types)の設定に注意

ここで、[Makefile project]を選択した場合は、Makefileを作成しなければエラーになります。[static ライブラリー]を選択した場合はビルドしてもバイナリファイルは生成されないので注意です。

雑感

最近はC, C++, C#やJavaにしても統合開発環境があればコーディングやリーディングがしやすいです(ソースの規模にもよりますが)。これを使うことでの弊害も無いとは言えないですが、それはまた別の話で。
RubyやRails, PHPの開発ではどうなのかな。

プロセスの監視&自動復旧(簡易版)

プロセス監視シェルスクリプトの実行結果

先日書いたシェルスクリプトでプロセスを監視し自動実行&自動killのシェルスクリプトは、その後結局使わず、さらに簡易的なコードで済ませました。

クエリーサーバのチェックスクリプト

scheckp.sh

#!/usr/bin/sh
while true
do
  isAliveSev=`ps -ef | grep "/server" | grep -v grep | wc -l`
  if [ $isAliveSev = 1 ]; then
    echo "o:server process"
  else
    echo "x:server process"
    /ret/sev/server &
  fi
  sleep 300 # モニター間隔(秒単位)
done

エンジンサーバのチェックスクリプト

echeckp.sh

#!/usr/bin/sh
while true
do
  isAliveEng=`ps -ef | grep "/engine" | grep -v grep | wc -l`
  if [ $isAliveEng = 1 ]; then
    echo "o:engine process"
      else
    echo "x:engine process"
    /ret/eng/engine &
  fi
  sleep 300 # モニター間隔(秒単位)
done

Ruby: メソッドの引数にブロックを渡す

ブロックの使い方を練習してみます。

def repeat(n)
  n.times { yield } if block_given?
end
repeat(2) { puts "Hello." }
# Hello.
# Hello.

メソッドに渡したブロックはyieldを用いて呼び出します。
似たような例としてもう一つ。

# nからmまでの自然数の合計を求める
def sumup(n, m, sum=0)
  (n..m).each { |x|
    # yield でブロックを呼び出す
    yield if block_given? # 引数にブロックが与えられている
    puts x
    sum += x
  }
  puts "Sum : #{sum}"
end
sumup(2, 4) { printf "Add : " }
#Add : 2
#Add : 3
#Add : 4
#Sum : 9

渡されたブロックはProcオブジェクトに変換されるのでcallを用いて呼び出すことも出来ます。下の例で確認してみます。

# nからmまでの自然数の合計を求める
def sumup(n, m, &block)
  sum = 0
  (n..m).each { |x|
    block.call if block # ブロックを呼び出し
    puts x
    sum += x
  }
  puts "Sum : #{sum}"
end
sumup(0, 4) { printf "Add : " }
#Add : 0
#Add : 1
#Add : 2
#Add : 3
#Add : 4
#Sum : 10

最後に、渡されたブロックをまた引数として渡す場合の例を示します。
その際、ブロック変数名の前に「&」をつけます。

# 配列内の最小値を求める
def minimum(arr, &block)
  block  ? arr.select(&block).min : arr.min
end
arr = [20,48,15,67]
p minimum(arr) {|i| i > 30}
#=> 48
Page 1 of 3123

Home > Archives > 2008-01

バックナンバー
最近のコメント
最近のトラックバック
メタ情報

Return to page top