int型の0を識別したい

[戻る]
ikuta 2007/10/12(金) 18:57:08
モーダルダイアログのエディットボックスに入力されたint型の値numberがあります。 
ダイアログのOKボタンが押下されて、 
void CInputDlg::OnOK()関数にいきます。 
関数の中で 

void CInputDlg::OnOK() 
{ 
  // エディットで入力された値を取得 
  UpdateData(); 

  // IDC_NUMBERはモーダルのエディットボックスID 
  int number = GetDlgItemInt(IDC_NUMBER); 

  if (number == 0) 
  { 
    AfxMessageBox("0が入力されました"); 
    return; 
  } 
} 
エディットボックスで0が入力されても値が未入力でもnumberには0がはいります。 
値が未入力の時にはUpdateData()関数内で「整数を入力して下さい」のメッセージボッ
クスが表示されたあとにnumberに0がはいります。 

エディットに未入力の場合、 
「整数を入力して下さい」 
「0が入力されました」 
と二回メッセージボックスが表示されるので表示されないようにしたいのですがよろし
くお願いします。

ソイレントグリーン 2007/10/12(金) 19:30:50
一手間増えますが、エディットボックスに入る値の型をchar型に変えて
atoiでint型に変換したらどうでしょうか

ikuta 2007/10/12(金) 19:47:03
ありがとうございます。

できれば前後のint型は変えないですすめたいのですが…。

yoh2 [E-Mail] 2007/10/12(金) 20:23:22
CWnd::GetDlgItemInt()の第2引数(デフォルト引数としてNULLが設定されることになっています)
を活用しましょう。

http://msdn2.microsoft.com/ja-jp/library/c7t43w0s(VS.80).aspx

菟ー 2007/10/12(金) 21:37:53
まずい箇所。
1、UpdateDataの戻り値をチェックしてない。
  これで、「整数を入力して下さい」は回避できる。
2、UpdateDataを使うってことは、メンバ変数化されてる前提で。
  GetDlgItemIntは使わない。自作DDX_Textを作ってDDX内で判断するべし。

菟ー 2007/10/12(金) 21:48:59
2の方法は、私が良く使う手段です。
自宅なのでソースが無いですが・・・。

「エディットは数値入力のみだが、値未定の場合は何も表示しない」
「普段は整数のみだが、実数入力は少数点以下4桁で丸める」
って、よく良くある要求なのでMFCでサラッと済ませると楽。

ikuta 2007/10/12(金) 22:12:57
yoh2さん、よくわかりましたが、引数に何を入れればいいのかがちょっとわかりません
でした。

菟ーさん、戻り値チェックしてみたいと思います。DDX_Text使ってやってみたいと思い
ます。今回は値未定でもメッセージを表示したい方向でやっているのでメッセージ出し
たいんですよね。
MFC活用してみたいとも思います。

菟ー 2007/10/12(金) 23:15:29
yoh2さんではありませんが、

GetDlgItemIntの第二引数には、ご自分で「これは特別なんだよ!」って値を指定する。
(たとえば、"999999"とか)
それで空文字を回避しなさい。ってアドバイスだと思う。<yoh2さん

GetDlgItemIntは、ただ単にatoiをラップしてるだけと想像。


DDX内で判定するとうれしい点はOnOK()がシンプルになるw

void CInputDlg::OnOK() 
{ 
  if( !UpdateData() )
  {
    return; 
  }

  CDialog::OnOK() ;
}

菟ー 2007/10/12(金) 23:29:54
って、やっとMSDNが開いた。激重い・・
ああ、BOOLのポインターだったかwww^^;

成否を知りたい時に使えってことね(アセ

yoh2 [E-Mail] 2007/10/13(土) 12:12:49
> yoh2さん、よくわかりましたが、引数に何を入れればいいのかがちょっとわかりません
> でした。

んー、どこで引っ掛かっているんだろ。MSDNに書かれている通りで、そこへのリンクも
前回記述した通りなんですが。

まず、第2引数が取るのはBOOLへのポインタ型です。
で、その意味合いは以下の通り。

MSDNより引用:
| 数字以外の文字を見つけたり、指定された最大値を越えたりするようなエラーが
| 発生する場合、GetDlgItemInt 関数は lpTrans が示す位置に 0 をコピーし
| ます。エラーが発生しなかった場合は、lpTrans には 0 以外の値を設定します。

要するにこう使えばよいということ。

    BOOL translated;
   int number = GetDlgItemInt(IDC_NUMBER, &translated);

    if(!translated){
        // ここに来たら数値取得失敗(未入力、オーバーフロー等)
        ...
    }

<余談>
> GetDlgItemIntは、ただ単にatoiをラップしてるだけと想像。

atoiではなく、SDKのGetDlgItemIntをラップしていますね。
</余談>

ikuta 2007/10/14(日) 19:39:35
菟ーさん、
void CInputDlg::OnOK()
{ 
int check = UpdateData(); 

if (check == 0) 
{ 
return; 
} 

int number = GetDlgItemInt(IDC_EDT_CAPACITY);//ID確認☆ 

if (number == 0) 
{ 
AfxMessageBox("0は入力不可"); 
return; 
} 
}

ikuta 2007/10/14(日) 19:46:42
[[解決]]
上のは間違って送信したのでスイマセン。

菟ーさん、

if文の中で一気にUpdateData()すればよかったのですね。一度UpdateData()してからも
う一度if文の中でしてしまったのでメッセージが二度表示されていました。

yoh2さん、

MSDNをちゃんと読んで試行錯誤したらyoh2さんのような文が書け無事に第二引数使う方
もわかりました。読まない内にわからないなどと言ってしまって答えまで書いてもらっ
てすいませんでした。
そのままBOOL型のポインタ使って判定するだけでした。

解決しました。ありがとうございました。

古いスレッドには追加発言できません。