mfc-ml

2004年01月

31

[mfc 47996] Re:char型の比較にておかしな動作

"bob" <b...@ctb.ne.jp> wrote:
> char型は、"/J"コンパイルオプションとか付けていないと、
> デフォルトはsigned charです。

そう言うオプションもあったんですね。

Tadamasa Teranishi <y...@asahi-net.or.jp> wrote:
> (char)0x96 が、負の値になって 
> psMem->szNameF[i+1] <= (char)0x96 の条件を満たしていないような
> 気がします。
そうですね。
/Jオプションのヘルプにも、
「/J オプションが必要になるのは、最終的に英語以外の言語に翻訳する
文字データを扱う場合です。」
等と書かれており、全角文字や文字コード間変換時には、案外、陥りやすい
初歩的な問題でした。
とりあえずunsigned charを付けて対応しました。

あと、大久保さんも有り難う御座いました。

中原
31

[mfc 47995] Re: char型の比較にておかしな動作

大久保です。


Reply to "[mfc 47990] char型の比較にておかしな動作"
(Message-Id: <20040131202804.130A.NAKAHARA@inst.ne.jp>
at Sat, 31 Jan 2004 20:56:43 +0900, nakahara wrote)
> 3 if (psMem->szNameF[i+1]>=(char)0x40 && psMem->szNameF[i+1] <= (char)0x96) {
> 4 ほにゃらら;
> 5 }
> 6 }
> 1の部分で、psMem->szNameF[i]は0x83で問題なく通過、
> 3の部分で、psMem->szNameF[i+1]は0x7eですが、なぜか「ほにゃらら」に行かずに6に飛びます。

VC++ではcharはデフォルトで符号付き型ですから,3行目は
if (psMem->szNameF[i+1]>=64 && psMem->szNameF[i+1] <= -106) {
という意味になります。故に,この式は常に負です。
if ((unsigned)psMem->szNameF[i+1]>=0x40 && (unsigned)psMem->szNameF[i+1] <= 0x96) {
のように書く必要があります。


では。


-- 
大久保 雄介(Okubo Yusuke)
mailto:y...@n01.itscom.net , mailto:y...@js5.so-net.ne.jp
31

[mfc 47994] Re:char型の比較にておかしな動作

charは、0x80以上はマイナスになってしまう事をすっかり忘れてました。

> 3 if (psMem->szNameF[i+1]>=(char)0x40 && psMem->szNameF[i+1] <= (char)0x96) {
は、
(char)0x7e(psMem->szNameF[i+1])はプラスで、(char)0x96はマイナスとなってしまいます…。

if ((UCHAR)psMem->szNameF[i+1]>=(UCHAR)0x40 && (UCHAR)psMem->szNameF[i+1] <= (UCHAR)0x96) {
で解決しました。

基本的な部分でした。みなさん、お騒がせしてすみません。

On Sat, 31 Jan 2004 20:59:21 +0900
nakahara <n...@inst.ne.jp> wrote:

> OS Windows2000,開発ツール VC/C++ 6.0
> ActiveXとして作成、構造体メンバのアライメント8。使用するランタイムライブラリ・マルチタスク。

> でS-JISの全角判定しているルーチンの一部、char型の比較にて意図しない動作をする部分があり、
> 質問させて頂きたいと思います。
> まず、そのおかしな動きをするソース部分の抜粋ですが、

> 1 } else if (psMem->szNameF[i]==(char)0x83) {
> 2 // 0x83
> 3 if (psMem->szNameF[i+1]>=(char)0x40 && psMem->szNameF[i+1] <= (char)0x96) {
> 4 ほにゃらら;
> 5 }
> 6 }

> psMemは以下の様な宣言になっており、実態を持っています。
> struct {
>  char szNameF[MAX_NAMESTR]; // MAX_NAMESTR=80
>  ....
> } *psMem;

> 1の部分で、psMem->szNameF[i]は0x83で問題なく通過、
> 3の部分で、psMem->szNameF[i+1]は0x7eですが、なぜか「ほにゃらら」に行かずに6に飛びます。
> アセンブラで3の行を確認すると、以下の様になっています。

> a mov         ecx,dword ptr [ebp+8]
> b  add         ecx,dword ptr [ebp-10Ch]
> c movsx       edx,byte ptr [ecx+6Fh]
> d cmp         edx,40h
> e jl          foo+3BBh (0234acfb)
> f mov         eax,dword ptr [ebp+8]
> g add         eax,dword ptr [ebp-10Ch]
> h movsx       ecx,byte ptr [eax+6Fh]
> i cmp         ecx,96h
> j jg          foo+3BBh (0234acfb)
> k ほにゃらら:

> ステップ実行でiの部分まで来るため、最初の比較には成功している様ですが、iのecxには0x0000007eが
> 入っており、cmpを通過後、jの"jg"では飛ばないはずだと思うのですが、飛んで行きます。
> 基本的な部分で間違いが無いかを確認しているのですが、どうも分かりません。
> psMem->szNameF[ ]はchar型ですが、念のため、この変数にキャストしてみても結果は同じでした。
> また、リコンパイルしても結果は同じでした。
> どなたかアドバイスをお願いします。

> 中原

中原
31

[mfc 47993] Re: char型の比較にておかしな動作

こんにちは、bobです。

char型は、"/J"コンパイルオプションとか付けていないと、
デフォルトはsigned charです。
unsigned charに統一したほうが良いかと思います。
それでは。。。
31

[mfc 47992] Re:char型の比較にておかしな動作

寺西です。

# 外しているかもしれませんが...。

nakahara wrote:

> 1       } else if (psMem->szNameF[i]==(char)0x83) {
> 2               // 0x83
> 3               if (psMem->szNameF[i+1]>=(char)0x40 && psMem->szNameF[i+1] <= (char)0x96) {
> 4                       ほにゃらら;
> 5               }
> 6       }
 
char にキャストするのをやめて、psMem->szNameF[i+1] を unsigned char
にキャストすれば動くのでは?

(char)0x96 が、負の値になって 
psMem->szNameF[i+1] <= (char)0x96 の条件を満たしていないような
気がします。
-- 
=====================================================================
寺西 忠勝(TADAMASA TERANISHI)  y...@asahi-net.or.jp
http://www.asahi-net.or.jp/~yw3t-trns/index.htm
Key fingerprint =  474E 4D93 8E97 11F6 662D  8A42 17F5 52F4 10E7 D14E
記事検索
Amazon.co.jp
  • ライブドアブログ