• ベストアンサー

C言語のisgraph

C言語のisgraph関数 <C++> UINT uint = 66; if(isgraph(uint)){} をPerlに書き換えようとしたんですが、 <Perl> $uint = 66; if(??? =~ /[:graph:]/){} ここまでしか分かりませんでした。 Perlへの正しい変換を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

細かいことですが、isgraphに対応するのは、 [:graph:]ではなくて、[:print:]じゃありませんか? ([:graph:]は0x20含んでますから) sub isgraph {   my $key = shift @_;   $key =~ /^[\x21-\x7E]+$/ ? return 1 : return 0; } このような感じで書いておけば、 C同様、 if(isgraph($value)){ … } でいけます。 (エラーチェックなどは省略してますが) コードを渡したいのであれば文字に変換を一行追加する必要がありますけれど。

iufansu
質問者

お礼

$uint = 0x20; if(pack("C",$uint) =~ /[[:graph:]]/){ print 'TRUE'; } else { print 'FALSE'; } は、natsuki_tkさんと異なる結果で、Cと同じくFALSEを得ることができました。 ロケールの違いでしょうか。 上の訂正がこのことでしょうか? でも、natsuki_tkさんの/[\x21-\x7E]/の方が速いでしょうし、 packも必要ないからそれを使うことにして、[:graph:] は使わないことにしました。 将来、isgraphの範囲の定義が変更されることを考えれば [:graph:]を使用した方がいいんでしょうけど。 ありがとうございました。

その他の回答 (5)

回答No.6

>$c = ' '; # $c = ('c', 0x20); >printf("'%s' is NOT a graphic character.\n", $c) if ($c !~ /[[:graph:]]/); >はちゃんと真になりましたよ? 申し訳ありません。 印刷可能と表示可能を勘違いしておりました。 graph [:alnum:] [:punct:] print [:alnum:] [:punct:] 空白 ですので、この場合[:graph:]で全く問題無いのですね(^^; ろくに確認もせずすみませんでした。

  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.5

お礼をどうもありがとうございます。まず、補足くださった疑問点から 片付けていきましょう。 >[]の2重についてのことが分からないんですが、正規表現の >[abc] #aかbかcのorという意味 >というorの意味が、/[[:graph:]]/の内か外の[]にあてはまりますか? 文字クラスの意味は、No.2 の方のご説明通りです。「[:alpha:]」を例にとって考えれば、 「[[:alpha:]]」は「[ABC..Za..z]」のように要素を列挙するのではなく、 「[A-Za-z]」のように範囲指定しているものだと思います。だから、 >[:graph:]でひとつの文字クラスです。文字クラスは[]で囲んで表現しますから、 >[[:graph:]]でワンセットです。 便宜的に「[:alpha:]」は「A-Za-z」に置き換わると考えてください。 つまり、「/[[:alpha:]]/」として初めて「/[A-Za-z]/」の意味になります。 これを角括弧を外して、「/A-Za-z/」と書いては意味を成しませんね。 ですから、以下のコードは間違いということになります。 >if ($c =~ /[:graph:]/) {...} 次はPOSIX モジュールを使う場合の補足です。 回答 No.3 のように書くと POSIX 準拠の関数すべてがインポート(輸入) されてしまいますので、無駄を省くために use POSIX qw(isgraph); # isgraph のみインポート または use POSIX qw(:ctype_h); # 標準ヘッダ ctype.h で定義されているシンボルをすべてインポート としてください。 それから、if や unless は文修飾子として用いたほうが一層効率的です。 printf("'%s' is a graphic character.\n", $c) if ($c =~ /[[:graph:]]/); 最後に No.4 の方のご指摘について。 >細かいことですが、isgraphに対応するのは、 >[:graph:]ではなくて、[:print:]じゃありませんか? >([:graph:]は0x20含んでますから) そうなのですか?Cでの定義とは異なりますね。 (Cの is 系関数は文字1個しか引数に取れないところも違いますが) でも、手元の Perl v.5.6.1(Turbolinux Workstation 8.0 上の)では、 $c = ' '; # $c = ('c', 0x20); printf("'%s' is NOT a graphic character.\n", $c) if ($c !~ /[[:graph:]]/); はちゃんと真になりましたよ? ホワイトスペースは定義通り弾かれているようですが。

iufansu
質問者

お礼

[]が2重になる理由が理解できました。 POSIXは使ったことがなくて分かりませんでしたが、Perlへの移植が成功したのでまんぞくしました。 ありがとうございました。

  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.3

こんにちは。文字コードから文字への変換には pack 関数を使います。 $c = pack('c', $uint); そしてこの文字を使います。 if ($c =~ /[[:graph:]]/) {...} こういう書き方もできるようです。 if ($c =~ /\p{IsGraph}/) {...} ただし、文字としてありえない値を与えたときの挙動は両者で異なります。 前者は黙って無視しますが、後者は "Malformed UTF-8 character" 何とかかんとかというエラーが出ます。"$uint = 1000;" などで試してみてください。 おなじみの is 系関数を使いたいならば、POSIX モジュールを使うのが簡単でしょう。 use POSIX; $c = pack('c', $uint); if (isgraph($c)) {...}

参考URL:
http://sk.redbit.ne.jp/~letzh/perl/sc/14.html
iufansu
質問者

補足

こんにちは。 []の2重についてのことが分からないんですが、正規表現の [abc] #aかbかcのorという意味 というorの意味が、/[[:graph:]]/の内か外の[]にあてはまりますか? あてはまるとすると、 if ($c =~ /[:graph:]/) {...} のようなソースもありえることになると思いますが、 if ($c =~ /[:graph:]/) {...} のようなソースはありえるんでしょうか? is...のようなものは、必ず/[[...]]/のように、最低でも[]が2つ必要なんでしょうか?

noname#5910
noname#5910
回答No.2

ご質問が「isgraph()を使うようなシチュエーションで、Perlのやり方でうまくやりたい」のか、「Perlを使ってisgraph()とまったく仕様が同じ関数を実装したい」のかどちらなのか分からないので、前者と仮定してお答えします。 C言語ではcharが数値を保持する型であるため、文字の判定関数は引数をintで受けるものが多いようですが、Perlでは文字を扱う演算子や関数に数値を与えることはできません。そのため66ではなく文字リテラルで'B'と書く必要があります。 それから、[:graph:]でひとつの文字クラスです。文字クラスは[]で囲んで表現しますから、[[:graph:]]でワンセットです。 以下のコードを実行すると"True"と表示されます。 $uint = 'B'; if ($uint =~ /[[:graph:]]/) {print "True\n"}

iufansu
質問者

補足

ありがとうございました。 []の理解が間違っていたみたいで $uint = 66; if(pack("C",$uint) =~ /[[:graph:]]/){  print 'TRUE'; } else {  print 'FALSE'; } のように[]を2重にするとできました。 Perlの:graph:の動作とは無関係で、C言語のisgraph()関数 の移植なんですが、ロケールは考えないとしてこれでいいですか?

  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.1

int isgraph(int c);  次の文字に一致したらゼロ以外の値を、一致しなければゼロ返します  スペース ( ' ' ) を除く印字可能文字( ASCIIコードの0x21-0x7E ) この意味を考えて、Perl版を作成してください。 http://www1.cts.ne.jp/~clab/hsample/Func/Func05.html

参考URL:
http://www1.cts.ne.jp/~clab/hsample/Func/Func05.html

関連するQ&A

専門家に質問してみよう