ForNext
Only Do What Only You Can Do
2.1. TAB の復元
VBScript
JScript
Perl
更新日 : 2008.12.26
use strict; #****************************************************************************** # TAB の 復元 #****************************************************************************** my $c = ""; my $EOF = "\0"; my $NEWLINE = "\n"; my $TAB = "\t"; my $BLANK = " "; my $col_read = 0; my $col_write = 0; my @tabs = []; my $MAXCOL = 80; settab(); while (($c = get_char()) ne $EOF) { # 空白なら if ($c eq $BLANK) { # 出力せずに、読み込み現在位置を1つ進める $col_read++; } # TABなら elsif ($c eq $TAB) { # 出力せずに、読み込み現在位置をTAB位置まで進める ++$col_read while (!tabpos($col_read)); } # 改行コードなら elsif ($c eq $NEWLINE) { # 改行コードを出力 put_char($c); # 読み込み現在位置をクリア $col_read = 0; # 書き込み現在位置をクリア $col_write = 0; } # 空白でもTABでも改行コードでもなかったら else { # 読み込み現在位置と書き込み現在位置が一致していない if ($col_read ne $col_write) { # 書き込み現在位置から、読み込み現在位置まで my $col; for $col ($col_write+1 .. $col_read) { # TAB位置なら if (tabpos($col)) { # TABを出力 put_char($TAB); # 書き込み現在位置をTAB位置まで進める $col_write = $col; } } # 書き込み現在位置から、読み込み現在位置まで for (; $col_write < $col_read; $col_write++) { # 空白で埋める put_char($BLANK); } } # 読んだ文字をそのまま出力 put_char($c); # 読み込み現在位置を文字幅だけ進める $col_read += length($c); # 書き込み現在位置を文字幅だけ進める $col_write = $col_read; } } #============================================================================== # TAB 位置 の 初期設定 #============================================================================== sub settab { for (1.. $MAXCOL) { $tabs[$_ - 1] = ($_ % 4 == 0); } } #============================================================================== # TAB 位置か? #============================================================================== sub tabpos { my ($col) = @_; if ($col > $MAXCOL) { for (($MAXCOL + 1)..$col) { $tabs[$_ - 1] = ($_ % 4 == 0); } } $MAXCOL = $col; return $tabs[$col - 1]; } #============================================================================== # 1文字 取得 #============================================================================== my $current_line = ""; my $pos = -1; sub get_char { my $char; # まだ読んでなかったら if ($current_line eq "") { # 1行読む $current_line = <STDIN>; # ファイルの終わりなら 終了 return $EOF if (!$current_line); # 改行コードを取り除く chomp($current_line); # 現在位置 クリア $pos = 0; } # 行の終わりに達したら if ($pos >= length($current_line)) { # 現在行 クリア $current_line = ""; # 行の終わりを 知らせる return $NEWLINE; } # 半角 / 全角 if (substr($current_line, $pos, 1) =~ /^[\x80-\xff]/) { # 2バイト取得 $char = substr($current_line, $pos, 2); $pos += 2; } else { # 1バイト取得 $char = substr($current_line, $pos, 1); $pos++; } return $char; } #============================================================================== # 1文字 出力 #============================================================================== my $buffer = ""; sub put_char { ($_) = @_; if ($_ eq $NEWLINE) { # 行の終わりなら 出力 print $buffer, "\n"; $buffer = ""; } else { # 行の終わりでなければ、バッファにためる $buffer .= $_; } }
PHP
更新日 : 2008.12.26
<?php #****************************************************************************** # TAB の 復元 #****************************************************************************** $c = ""; $EOF = "\0"; $current_line = ""; $pos = -1; $NEWLINE = "\n"; $buffer = ""; $TAB = "\t"; $BLANK = " "; $col_read = 0; $col_write = 0; $tabs = array(); $MAXCOL = 80; settab(); while (($c = get_char()) != $EOF) { # 空白なら if ($c == $BLANK) { # 出力せずに、読み込み現在位置を1つ進める $col_read++; } # TABなら else if ($c == $TAB) { # 出力せずに、読み込み現在位置をTAB位置まで進める while (!tabpos(++$col_read)); } # 改行コードなら else if ($c == $NEWLINE) { # 改行コードを出力 put_char($c); # 読み込み現在位置をクリア $col_read = 0; # 書き込み現在位置をクリア $col_write = 0; } # 空白でもTABでも改行コードでもなかったら else { # 読み込み現在位置と書き込み現在位置が一致していない if ($col_read != $col_write) { # 書き込み現在位置から、読み込み現在位置まで for ($col = $col_write+1; $col <= $col_read; $col++) { # TAB位置なら if (tabpos($col)) { # TABを出力 put_char($TAB); # 書き込み現在位置をTAB位置まで進める $col_write = $col; } } # 書き込み現在位置から、読み込み現在位置まで for (; $col_write < $col_read; $col_write++) { # 空白で埋める put_char($BLANK); } } # 読んだ文字をそのまま出力 put_char($c); # 読み込み現在位置を文字幅だけ進める $col_read += strlen($c); # 書き込み現在位置を文字幅だけ進める $col_write = $col_read; } } #============================================================================== # TAB 位置 の 初期設定 #============================================================================== function settab() { global $MAXCOL; global $tabs; for ($i = 1; $i <= $MAXCOL; $i++) { $tabs[$i - 1] = ($i % 4 == 0); } } #============================================================================== # TAB 位置か? #============================================================================== function tabpos($col) { global $MAXCOL; global $tabs; if ($col > $MAXCOL) { for ($i = $MAXCOL + 1; $i <= $col; $i++) { $tabs[$i - 1] = ($i % 4 == 0); } } $MAXCOL = $col; return $tabs[$col - 1]; } #============================================================================== # 1文字 取得 #============================================================================== function get_char() { global $fp; global $EOF; global $current_line; global $pos; global $NEWLINE; $char = ""; # まだ読んでなかったら if ($current_line == "") { # まだ OPEN してなかったら if ($pos == -1) { $fp = fopen("php://stdin", "r"); } # 1行読む $current_line = fgets($fp); # ファイルの終わりなら 終了 if (feof($fp)) { fclose($fp); return $EOF; } # 改行コードを取り除く $current_line = rtrim($current_line, "\n\r"); # 現在位置 クリア $pos = 0; } # 行の終わりに達したら if ($pos >= strlen($current_line)) { # 現在行 クリア $current_line = ""; # 行の終わりを 知らせる return $NEWLINE; } # 半角 / 全角 if (mb_ereg('^[\x80-\xff]', substr($current_line, $pos, 1))) { # 2バイト取得 $char = substr($current_line, $pos, 2); $pos += 2; } else { # 1バイト取得 $char = substr($current_line, $pos, 1); $pos++; } return $char; } #============================================================================== # 1文字 出力 #============================================================================== function put_char($char) { global $NEWLINE; global $buffer; if ($char == $NEWLINE) { # 行の終わりなら 出力 echo $buffer, "\n"; $buffer = ""; } else { # 行の終わりでなければ、バッファにためる $buffer .= $char; } } ?>
Python
Ruby
更新日 : 2008.12.26
#****************************************************************************** # TAB の 復元 #****************************************************************************** #============================================================================== # 1文字 取得 #============================================================================== $current_line = [] $pos = -1 $NEWLINE = "\n" $EOF = "\0"; def get_char # まだ読んでなかったら if $current_line.size == 0 # 1行読む line = $stdin.gets # ファイルの終わりなら 終了 return $EOF unless line # 改行コードを取り除く line.chomp!; # 文字の配列に分解 $current_line = line.split(//s) # 現在位置 クリア $pos = 0; end # 行の終わりに達したら if $pos >= $current_line.size # 現在行 クリア $current_line = [] # 行の終わりを 知らせる return $NEWLINE; end char = $current_line[$pos] $pos += 1 return char end #============================================================================== # 1文字 出力 #============================================================================== $buffer = "" def put_char(char) if char == $NEWLINE # 行の終わりなら 出力 puts $buffer $buffer = "" else # 行の終わりでなければ、バッファにためる $buffer << char end end #============================================================================== # TAB 位置 の 初期設定 #============================================================================== $tabs = []; $MAXCOL = 80; def settab() for i in (1.. $MAXCOL) $tabs[i - 1] = (i % 4 == 0) end end #============================================================================== # TAB 位置か? #============================================================================== def tabpos(col) if (col > $MAXCOL) for i in (($MAXCOL + 1)..col) $tabs[i - 1] = (i % 4 == 0) end end $MAXCOL = col return $tabs[col - 1]; end #============================================================================== # TAB の 復元 #============================================================================== c = "" TAB = "\t" BLANK = " " col_read = 0 col_write = 0 settab while (c = get_char) != $EOF # 空白なら if (c == BLANK) # 出力せずに、読み込み現在位置を1つ進める col_read += 1 # TABなら elsif (c == TAB) # 出力せずに、読み込み現在位置をTAB位置まで進める col_read += 1 while (!tabpos(col_read)) # 改行コードなら elsif (c == $NEWLINE) # 改行コードを出力 put_char c # 読み込み現在位置をクリア col_read = 0 # 書き込み現在位置をクリア col_write = 0 # 空白でもTABでも改行コードでもなかったら else # 読み込み現在位置と書き込み現在位置が一致していない if (col_read != col_write) # 書き込み現在位置から、読み込み現在位置まで for col in col_write+1 .. col_read # TAB位置なら if (tabpos(col)) # TABを出力 put_char TAB # 書き込み現在位置をTAB位置まで進める col_write = col end end # 書き込み現在位置から、読み込み現在位置まで for col_write in col_write .. col_read-1 # 空白で埋める put_char BLANK end end # 読んだ文字をそのまま出力 put_char c # 読み込み現在位置を文字幅だけ進める col_read += c.length # 書き込み現在位置を文字幅だけ進める col_write = col_read end end