C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: MFCでのTryParseの様な関数はある?


(過去ログ 123 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■73481 / inTopicNo.1)  MFCでのTryParseの様な関数はある?
  
□投稿者/ nobb (61回)-(2014/10/01(Wed) 09:00:14)

分類:[C/C++] 

2014/10/01(Wed) 09:05:26 編集(投稿者)

ダイアログ上にテキストボックスがあり、そこに入力をしてもらうのですが、
その値が数値かを判断したい為、.NET Frameworkで言うTryParseのような関数はありますか?

自分で調べてみたところそのような関数が見つけられなかったので自作しようかと思っていますが、
車輪の再発明をしてしまっては悲しいので、確認の為に質問させてもらいました。

今考えてる方法は、http://hpcgi1.nifty.com/MADIA/Vcbbs/wwwlng.cgi?print+200512/05120008.txt このページのうち、
7レス目の方法と、_ismbcdigitを組み合わせて判断しようかと思っています。

== 環境の書き忘れの為追記 ==
Visual Studio 2008
MFC(マルチバイト文字セット)
開発OS:Windows 7
対象OS:Wnidows Vista以上
引用返信 編集キー/
■73482 / inTopicNo.2)  Re[1]: MFCでのTryParseの様な関数はある?
□投稿者/ とっちゃん (255回)-(2014/10/01(Wed) 10:37:12)
とっちゃん さんの Web サイト
No73481 (nobb さん) に返信
> ダイアログ上にテキストボックスがあり、そこに入力をしてもらうのですが、
> その値が数値かを判断したい為、.NET Frameworkで言うTryParseのような関数はありますか?
>
MFCのダイアログなら、DDX を使う方法ではダメですか?

変数割り当てなどをすると、DoDataExchange にいろいろとセットしてくれます。
この部分で使われている仕組みの総称をDDXといいます。

ヘルプにも出てると思うので、一度見てみるとよいかもしれません。

が、あまり高性能ではないので、もっと高度なことがしたい場合は
自作するかそういうライブラリを探してくるかになります。

引用返信 編集キー/
■73486 / inTopicNo.3)  Re[2]: MFCでのTryParseの様な関数はある?
□投稿者/ nobb (62回)-(2014/10/01(Wed) 13:38:10)
No73482 (とっちゃん さん) に返信
いつもご回答ありがとうございます。
まずは書き忘れていた点を追加します..

入力された値を別に用意されている変数(の中の一部)に代入しなければならないため、
OnOk時に代入をしようと考えています。
そして、MFCで検証が走るのが基底クラスのCDialog::OnOk()時だったため、このタイミングでは無いと判断しました。
そこでOnOkをオーバーライドし、判断しようとした訳です。

が、なぜその判断に至ったかの理由を忘れてしまいました。。。
(整数ではない旨のエラーが出たことは覚えていますが、それでもダイアログが閉じたから・・・?さっぱり忘れてしまった・・・)

なので、一旦その理由を思い出す事に戻ろうかと思います。
思い出せた時にまたこの質問に追加したいと思いますのでよろしくお願い致します。

お手数お掛けして申し訳ありません。
引用返信 編集キー/
■73488 / inTopicNo.4)  Re[3]: MFCでのTryParseの様な関数はある?
□投稿者/ nobb (63回)-(2014/10/01(Wed) 14:24:08)
#思い出せた・・・・

一応箇条書きですがやりたい事を書きます。
・DlgAからDlgBを呼び出す。この際、CHogeのポインタを渡す。
・DlgBで入力された値をOnOk()でCHogeポインタに設定。OnCancel()なら何もしない。
・DlgAでIDOKなら計算

DDX_Textの変数としてint型の変数を用意すれば数値以外の時はエラーがでるのを確認しました。
しかし、OnOk()で代入を行いたいため、OnOk()をオーバーライドしています。
そこで基底クラスのCDialog::OnOk()を呼びますが、エラーがあった場合でも後続の処理が続行してしまうので
数値変換可能ならOnOk()を呼び出すという事をしたかった為です。

この様な状況ではやはり自作orいずこかのライブラリでしょうか?

# こんなの初めから書けよ という内容ですね。申し訳ありません。
引用返信 編集キー/
■73489 / inTopicNo.5)  Re[4]: MFCでのTryParseの様な関数はある?
□投稿者/ nobb (64回)-(2014/10/01(Wed) 15:02:02)
いろいろ試してみましたが、どうもDDXだけでは無理っぽいので自作することにします。

※int型変数でコントロールに設定(DDX_Text)しても入力値が「123あsd410」というケースの場合、
123のみ変数に入り、エラーになりませんでした。

※テキストボックスのNumberプロパティをtrueにした際は、テンキーのあるキーボードならテンキーからの入力でどうとでもなりそうですが
ノートPCのようなテンキーのないPCの場合は不便さを感じそう
解決済み
引用返信 編集キー/
■73490 / inTopicNo.6)  Re[4]: MFCでのTryParseの様な関数はある?
□投稿者/ とっちゃん (256回)-(2014/10/01(Wed) 15:04:22)
とっちゃん さんの Web サイト
No73488 (nobb さん) に返信

CDialog::OnOK() をそのまま呼び出さず、UpdateData() だけ呼び出せばよいのでは?

OnOK() は仮想関数ですので、必要があればオーバーライドすればよいと思いますし、
ダイアログの実装によっては、デフォルトの処理では困る場合も多々あるので、
OnOK(), OnCancel() あたりは多くのMFC製ダイアログがオーバーライドしていると思いますよ。

CDialog::OnOK()は、UpdateData() を呼び出し、成功したら EndDialog(IDOK);を呼ぶというシンプルな実装です。

必要があれば、UpdateData() だけにする、UpdateDataの後、必要に応じて CHoge にセットするなどでもいいと思いますよ。

また、DlgA のOnOKは、デフォルトを呼び出すのではなく、UpdateData() やその他チェックルーチンを通った後
計算処理を呼び出す(EndDialogしない)でいいと思います。

全然違いますが、カスタマイズ例として、以前勉強会で使ったサンプルコードをリンクしておきます。

http://blogs.wankuma.com/tocchann/archive/2014/01/20/328354.aspx

MFCのダイアログアプリ(本題部分はOnOKとかではない)がサンプルプロジェクトに入っていますので
参考程度に見てみてください。

OnOK や、OnCancel の内容が通常とは全く違う段取りになっています。

引用返信 編集キー/
■73494 / inTopicNo.7)  Re[5]: MFCでのTryParseの様な関数はある?
□投稿者/ nobb (65回)-(2014/10/01(Wed) 16:42:13)
No73490 (とっちゃん さん) に返信

> 必要があれば、UpdateData() だけにする、UpdateDataの後、必要に応じて CHoge にセットするなどでもいいと思いますよ。
UpdateData()の戻り値の説明に書いてある「正常終了した場合は...」って検証も含めてだったのか・・・
これで数値の検証はできますが、「123あ410」という間違った入力(実際は123410と入れたかった等)の場合切れてしまい(123になる)、
なおかつエラーにならないので入力した側は計算が合わないと思ってしまいます。
DlgBへの入力値はこのダイアログ以降は直接表示される事が無い仕様なので、(ユーザーががんばって計算する以外は)確認する事が困難ですので。。

テキストボックスのNumberプロパティへTrueを設定すればそもそも半角数字しか入らないのでそれを併用すればシンプルかもしれませんが
コピペされた場合は文字も受け入れてしまうので、入力された文字の監視みたいな事を実装しなければならないような・・
そんな事せずにUpdateData()に任せたいのですが、前述の「123あ456」問題があるから無理かなぁと思っています。

> 全然違いますが、カスタマイズ例として、以前勉強会で使ったサンプルコードをリンクしておきます。
>
> http://blogs.wankuma.com/tocchann/archive/2014/01/20/328354.aspx
> MFCのダイアログアプリ(本題部分はOnOKとかではない)がサンプルプロジェクトに入っていますので
> 参考程度に見てみてください。
> OnOK や、OnCancel の内容が通常とは全く違う段取りになっています。
ありがとうございます!
DLしたので、拝見させて頂きます!
引用返信 編集キー/
■73496 / inTopicNo.8)  Re[5]: MFCでのTryParseの様な関数はある?
□投稿者/ 774RR (179回)-(2014/10/01(Wed) 18:21:46)
とりあえず DDX の話をおいておいて
文字列→数値変換の定石は sscanf とか strtol とか strtod とかかな

変換の仕様が明示されていないのでアレだが
・いわゆる半角数字文字 U+0030 〜 U+0039 だけを認めるのか
・ int (32bit) を超えて __int64 なり、あるいはもっと長い桁数を認める必要があるか
・ +3.14 とか -2E4 とかの浮動小数点数になると数値以外の文字も使う必要がある
・国別フォーマットを認めるなら 3,14 のような記述も認める必要がある
・いわゆる CJK 全角数字 U+FF10 とかも変換できるべきなのか
・丸囲み数字 U+2460 とかも変換できるべきなのか
・ローマ数字とか、いわゆる「数値に準じる文字」なら何でも変換できるべきなのか
あたりで話は違ってきそう。

# 後半はかなりちゃちゃ入っているが
引用返信 編集キー/
■73497 / inTopicNo.9)  Re[6]: MFCでのTryParseの様な関数はある?
□投稿者/ とっちゃん (257回)-(2014/10/02(Thu) 00:00:19)
とっちゃん さんの Web サイト
No73494 (nobb さん) に返信
>>必要があれば、UpdateData() だけにする、UpdateDataの後、必要に応じて CHoge にセットするなどでもいいと思いますよ。
> UpdateData()の戻り値の説明に書いてある「正常終了した場合は...」って検証も含めてだったのか・・・
> これで数値の検証はできますが、「123あ410」という間違った入力(実際は123410と入れたかった等)の場合切れてしまい(123になる)、
> なおかつエラーにならないので入力した側は計算が合わないと思ってしまいます。

UpdateData() の主な仕事は、DoDataExchange()を呼び出すことです。

DoDataExchange() の主な仕事は、コントロールに入力されたデータを検証しつつダイアログクラスの変数に取り込むあるいは、
変数の内容をコントロールに反映させる作業となります。

コントロールに入力されたデータを取り込む場合は、必要に応じて検証(バリデート)が行われます。
ただし、MFCのDDXはそれほど高機能ではありませんので、あまり複雑な検証はしません。

また、DoDataExchange() はリアルタイムに呼び出されるわけではないため、エディットコントロールに
入力されている状況に追従するということもありません。

ですが、入力時点で対処したいのなら、それはバリデーションの仕事の範疇としては、エディットコントロール側に
処理を行わせるべきものになります(数値専用エディットコントロールを用意するという意味)。


> DlgBへの入力値はこのダイアログ以降は直接表示される事が無い仕様なので、(ユーザーががんばって計算する以外は)確認する事が困難ですので。。
>
> テキストボックスのNumberプロパティへTrueを設定すればそもそも半角数字しか入らないのでそれを併用すればシンプルかもしれませんが
> コピペされた場合は文字も受け入れてしまうので、入力された文字の監視みたいな事を実装しなければならないような・・
> そんな事せずにUpdateData()に任せたいのですが、前述の「123あ456」問題があるから無理かなぁと思っています。
>
どこまでOKでどこからNGにするかは、そのプログラムの動作仕様になるので何とも言えません。

また、入力時点で処理を施すなら、DoDataExchange ではできないので、
エディットコントロールに対処コードを載せるなどで対応することになります。

NumberプロパティをTrueにして、なおかつ、エディットコントロールのペーストロジックをトラップして
独自の処理を施すということになります。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -