• ベストアンサー

C言語のisgraph

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

  • Perl
  • 回答数6
  • ありがとう数12

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

  • ベストアンサー
回答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

  • perlで,c言語で言うところのatoiはできる?

    perlでキャラクタの数字を,スカラーの数字になるよう明記することってできますか? perlが勝手にキャラクタとスカラーの変更をしてしまうのを防ぎたいのですが・・・ c言語でのatoi関数のようなものはあるのでしょうか?

    • ベストアンサー
    • Perl
  • C言語について。

    ここでいうC言語のモジュールとは、関数の事でしょうか?教えていただけると嬉しいです。以下の文章です。 C言語のプログラムは、通常いくつかの関数によって構成されています。この関数とは、1つの処理単位を表すものでモジュールともいいます。

  • Perlで書いたプログラムをC言語に変換するツールはありますか?

    perlをEXEにするのは聞いたことがあるのですが Perlで書いたプログラムをC言語に変換するツールはありますか? WindowsのActivePerl5.8を使っています。 Linuxなら出来るのでしょうか?

    • ベストアンサー
    • Perl
  • C言語について。

    C言語プログラマとしては、スタートアップコードは・・・ ・自分が書いたプログラムを、直接動かすために必要なライブラリ ・それはコンパイル後、リンカによって追加されるライブラリこれは、 どういう意味でしょうか?分かりやすく教えていただけると幸いです。すみません。で、 以下のかぶくんまんさんの回答です。 https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11247611941 で、 C言語におけるプログラミングとは「main関数を書くこと」に他ならない。なぜ「main関数を書く」ことがC言語におけるプログラミングに他ならないのかと言えば、それは偏に「C言語のコンパイラはmain関数を呼び出すプログラムを生成するから」です。それがmain関数を求めるので結果的にmain関数がリンクされ、そしてmain関数が求めるままに他の関数もリンクされていくわけです。 で、その「main関数を呼び出すプログラム」こそが、C言語における「スタートアップコード」。 という回答で、main関数以降は、プログラマが書くのですよね?プログラマが関数をリンクさせる様なプログラムを書くということでしょうか?教えていただけると幸いです。すみません。 という所が分かりません。教えていただけると幸いです。すみません。以下のURL https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12247932542

  • 離散フーリエ変換をC言語でどの様に書けばいいですか?

    C言語でDFT離散フーリエ変換を書くにはどの様に書けばよろしいですか? Googleで検索すれば書き方は出てくるのですが、使ってる関数がいまいちよく分かりません。 ・データの入力 ↓ ・フーリエ変換の計算 ↓ ・結果の出力というのをやればいいのは理解できるのですが、C言語でどの様に書けばいいか分からなくて…

  • C言語について知りたい!!

    C言語を勉強しようと思ったのですが、 C言語って数学ができないとヤッパリ上達しないのでしないのでしょうか??それとも、別に数学はできなくてもC言語の知識をつける事は可能なのでしょうか?? C言語を勉強する上で必要になってくる数学って一体何でしょうか?? 関数とかでしょうか?? 必要になってくる数学の知識について教えてください! よろしくお願いしますm(_ _)m

  • C言語の自作関数がエラーになる

    C言語の自作関数がエラーになる 現在C言語でWindowsのプログラミングを学習中ですが あるプロトタイプ宣言した自作の関数がエラーになってしまいます。 エラー内容は「未解決の外部シンボル・・・」といった内容です。 関数の引数をHWNDだけにした場合は問題ありませんでした。 環境はMicrosoft Visual C++ 2008 Express Editionです。 自作関数の引数に型の制限はあるのでしょうか? よろしくお願いします。 以下コード一部です LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int MySave(TCHAR *,HWND,int); ・ ・ ・ LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { THCAR buffer[1024]; int iCount; ・ ・ ・ MySave(buffer,hWnd,iCount); ・ ・ ・ } int MySave(buffer,hWnd,iCount); ・ ・ ・ }

  • C言語より後に開発されたプログラミング言語は

    C言語を基にして開発されたのでしょうか? C++,C#はもちろんそうですが、Java、PHP、JavaScriptなどもそうなのでしょうか?と言うのも、C言語の関数とこれらのプログラミング言語の関数がかなり似ているところ(共通しているものも)があるからです。また、Excelの関数とも似ているのですが、これらのプログラミング言語と何か関係があるのでしょうか。

  • c言語でスタック領域の使われ方について

    c言語でスタック領域の使われ方について質問です。 メイン関数{ if(true){ } //if文終わり サブ関数1() サブ関数2() } このときのスタックのプッシュ、ポップの行われ方について教えてください。 自分の予想では以下のようになると考えていますが自信が全くありません・・・・ 1 まずメイン関数をプッシュ 2 if文をプッシュ     ???   <???が特に自信ないです。 3 if文をポップ      ??? 4 サブ関数1をプッシュ 5 サブ関数1をポップ   ??? 6 サブ関数2をプッシュ 7 サブ関数2をポップ   ??? 8 メイン関数をポップ もし知っていたら教えてください。 よろしくお願いします。

  • [C言語→アセンブリ言語]はどうするのですか?

    C言語でプログラムを作って、それをアセンブリ言語に変換したいのですが、どうしたらよいでしょうか?

専門家に質問してみよう