• ベストアンサー

char型の比較

C++で文字の比較をしたいのですが、コンソールアプリで   char str[3] = "困";   printf( "%x", str[0] ); と記述すると、"困"の文字コードは"8da2(Shift_JIS)"なので、   8d と表示されると思っていたのですが、実際は   ffffff8d と表示されます。 同じ理由で文字の比較をする際にも   str[0] == 0xffffff8d または   str[0] == (char)0x8d としなければ正しい結果が得られません。 これは何が原因なのでしょうか? よろしくお願いします。

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

  • ベストアンサー
noname#140082
noname#140082
回答No.3

省略時解釈の問題になります。 まず基本事項として、(char)0x8dと(int)0xffffff8dは、どちらも10進数で「-3」となります。 「0xnn」の定義の場合、省略時にはint型と解釈されます。 ですから正確には0x8dは「0x0000008d」となります。 また、str[0]との比較は大きい方の方に拡張されて比較されます。 ですから、str[0]と0x0000008dとの比較は、int型での比較になります。 また、char型,int型はどちらも符号付き整数ですので、符号付き整数値(int型)に拡張されます。 つまり、str[0]に0x8dが入っている場合、先頭ビットが符号となりますので、0xffffff8dと拡張されます。 結果的にstr[0]==0x8dの比較は 0xffffff8d==0x0000008dの比較となりますので、同じ値とはなりません。 逆に「(char)0x8d」は、そのままchar型として比較されますので、同じ値として判定されます。

ClickHere
質問者

お礼

ご回答ありがとうございます。 >先頭ビットが符号となりますので、0xffffff8dと拡張されます。 拡張時に先頭ビットが関係していることは初めて知りました。 実際に試してみると確かにその通りの動作をしました。 1つ新しい知識が付きました。ありがとうございます。

その他の回答 (4)

  • 5S6
  • ベストアンサー率29% (675/2291)
回答No.5

1です。 普通のcだと文字列の扱いが不便ですよね。 失礼しました。 比較だけであればstrcmpを使うとか、Stringクラスであればそのまま比較できます。 あとはsprintfを使う手もありますよ。こちらは以外と使えます。 '\0'も注意しましょう。

ClickHere
質問者

お礼

再度のご回答、ありがとうございます。 この度のサンプルでは載せていませんが、当初の目的はShift_JISで全角・半角の 分別を行いたかったからです。 その為、文字列判定は殆ど使うことはないでしょうね~。 >普通のcだと文字列の扱いが不便ですよね。 >失礼しました。 いえいえ、失礼だなんてとんでもない! 回答して頂けるだけでもとても助かっています。 何かご縁がありましたら、またお助け頂けると嬉しいです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

ただの char が符号付きか符号なしかは処理系に依存します. あなたが使っている処理系ではたまたま符号付きなのでこうなっているのでしょう. 符号なしの処理系があることも考えると, 書かれているように str[0] == (char)0x8d と明示的にキャストするか, あるいは str[0] == '\x8d' のように文字定数との比較にすることになるでしょう.

ClickHere
質問者

お礼

ご回答ありがとうございます。 '\x'というエスケープシーケンスがあるんですね。 char型にキャストするより打ち易いですが、可視性の面では微妙かもしれませんね。 選択肢の一つとして参考にさせて頂きました。

回答No.2

char型が符号付き8bitとして扱われているからでしょう。 その場合、0x8dは最上位ビットが1なので、負の数として扱われます。 printfに渡す場合は、char型からint型に昇格されるので、同値の負の数である0xffffff8dになってしまいます。 また、0x8dと比較する際も、そのままではintとの比較とみなされるため、同じ現象が起こるのだと思います。

ClickHere
質問者

お礼

ご回答ありがとうございます。 printf関数内では(他の関数・演算子内でも)変数の扱いが異なるんですね その点は初めて知りました。

  • 5S6
  • ベストアンサー率29% (675/2291)
回答No.1

%02x にしてみる

ClickHere
質問者

お礼

ご回答ありがとうございます。 せっかくのご回答を無下にしてしまうようで申し訳ありませんが、 printf関数のみの使用でしたら問題ないのですが printf関数を使用したのはあくまで値を確認する為ですので 変換指定子で制限しても根本的な解決には至りません。

関連するQ&A