変数の内容が数値かどうかを確認するにはどうしたらよいですか? - ページ 3

 
Ernst Van Der Merwe:
void OnStart()
  {
//---
   ObjectCreate("SimultaneousReleaseIndex1",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex1",OBJPROP_TEXT,"Four");
   ObjectCreate("SimultaneousReleaseIndex2",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex2",OBJPROP_TEXT,"44");
   ObjectCreate("SimultaneousReleaseIndex3",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex3",OBJPROP_TEXT,"Forty4");
   ObjectCreate("SimultaneousReleaseIndex4",OBJ_LABEL,0,0,0);
   ObjectSetString(0,"SimultaneousReleaseIndex4",OBJPROP_TEXT,".1234567890");
  
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex1",OBJPROP_TEXT)))
      Print("text1 is numeric");
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex2",OBJPROP_TEXT)))
      Print("text2 is numeric");
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex3",OBJPROP_TEXT)))
      Print("text3 is numeric");
   if(IsNumeric(ObjectGetString(0,"SimultaneousReleaseIndex4",OBJPROP_TEXT)))
      Print("text4 is numeric");
  }
//---
bool IsNumeric(string text)
  {
   int length=StringLen(text);
   for(int i=0;i<length;i++)
     {
      int char1=StringGetChar(text,i);
      if((char1>47 && char1<58) || char1==46)
         continue;
      else
         return(false);
     }
   return(true);
  }  
//+------------------------------------------------------------------+
サンプルコードをありがとうございました。しかし、あなたの "IsNumeric "キーワードはMQL4には属さないようです。間違っていたら訂正してください。しかし、あなたのコードは非常にうまく動作しており、これは私が求めていたものの完全な例です。ありがとうございました。
 
macpee しかし、あなたの「IsNumeric」キーワードはMQL4には属さないようです。間違っていたら訂正してください。
キーワードではなく、彼が上で提供した関数 です。
 
whroeder1:
キーワードではなく、彼が上で提供した機能 です。
ああ、私を見てください。知るべきでした。ありがとう、@whroeder1。
 
macpee:
ああ、私を見てください。気づくべきでした。ありがとうございます、@whroeder1 さん。
もちろん、ピリオド(.)はピリオドとゼロ(.0)が同じものと認識され、実際にはゼロ(0)なので、数値になるはずなんですけどね。さて、ピリオド(......)の数を増やしてみましたが、やはり数字として認識されます。最初のピリオドを引用した後、追加のピリオド(......)を排除するために、ピリオド(......)のコードが必要です。
if((char1>47 && char1<58) || char1==46)
ちなみに、そのコード(ASCIIと思われる)の一覧は見当たりません。

もうひとつは、負の数の入力方法だ。このコードでは、入力の最初だけ否定記号(-)を捕らえる必要がある。

さらに、このコードを完成させるためには(45-20)のような数字の途中でも否定記号(-)を受け入れて、引き算として扱って評価し、その結果がNumericであることをコード
int char1=StringGetChar(text,i);
を使って、結果がNumericであることをチェックする必要があります。このようなことは、2進法の基本的な4つの演算すべてについて可能です。しかし、それは今、私たちにとって重要ではありません。

全体のアイデアは、OBT_EDITのOBJPROP_TEXTプロパティに 経済カレンダー・データを受け入れて、それをそのまま数値として扱うようにすることなのです。そのために不必要に大きなコードを書かないようにするために、IsNumericの組み込み関数がかなり重要なのです。
 
macpee:
ピリオド(.)はピリオドとゼロ(.0)が同じものと認識され、実際にはゼロ(0)なので当然数字になるはずなのですが、ピリオド(...)の数を増やしてみても数字として認識されてしまいます。そこで、ピリオド(......)の数を増やしてみましたが、やはり数字として認識されてしまいます。最初のピリオドを引用した後、追加のピリオド(......)を排除するために、ピリオド(......)のコードが必要です。
if((char1>47 && char1<58) || char1==46)
ちなみに、そのコード(ASCIIと思われる)の一覧は見当たりません。

もうひとつは、負の数の入力方法だ。このコードでは、入力の最初だけ否定記号(-)を捕らえる必要がある。

さらに、このコードを完成させるためには(45-20)のような数字の途中でも否定記号(-)を受け入れて、引き算として扱って評価し、その結果がNumericであることをコード
int char1=StringGetChar(text,i);
を使って、結果がNumericであることをチェックする必要があります。このようなことは、2進法の基本的な4つの演算すべてについて可能です。しかし、それは今、私たちにとって重要ではありません。

全体のアイデアは、OBT_EDITのOBJPROP_TEXTプロパティに 経済カレンダー・データを受け入れて、それをそのまま数値として扱うようにすることなのです。そのために、不必要に大きなコードを書かないようにするために、IsNumericの組み込み関数がかなり重要なのです。
あるいは、IsNumericチェックの後に文字列をdoubleに変換するのが解決策かもしれません。
 

macpee:
Of course a period (.) should be numeric since (.) is regarded as the same thing with a period and zero (.0) which is in fact zero (0). Now I tried increasing the number of period (.....) and it is still recognizing it as numeric. We need the code for period (.) so as to eliminate additional period (....) once the first period has been cited in

もうひとつは、負の数の入力方法である。入力の最初だけ否定記号(-)を捕捉する必要があります。

ここにエコーがあるのか?

honest_knave さん

そうそう、そういうこと。

注意しなければならないのは

  • 小数点以下が複数ある場合 (通過してしまうが、通過させるべきではない)
  • 記号の使用 (通らないが、通るはず)
  • を千の区切り文字として、または小数点として使用すること(通らないが、通らなければならない)
  • 他の文字がない単独の小数点(合格だが不合格)
  • キャストの許容量を超える数字
  • スペース

________________________________

macpee です。

ところで、コードの一覧(ASCIIと思われる)が見当たりません。

さあ、やってみましょう。あなたの検索スキルを磨く機会をうかがっているのは知っています。

________________________________

macpee

全体のアイデアは、OBT_EDITのOBJPROP_TEXTプロパティに 経済カレンダーデータを受け入れて、それをそのまま数字として扱うようにすることです。そのために、不必要に大きなコードを書かないようにするために、IsNumericの組み込み関数がかなり重要なのです。

あなたの意図を誤解しているかもしれませんが、ユーザーがエディットボックスに日付を入力し、それをdatetimeとして解釈させたい場合(負の数に興味がある場合は違うかもしれません)、いくつかの理由からこれが最善の方法であるとは思えません。

 
honest_knave:

ここにエコーがかかっていますか?

________________________________

さあ、やってみましょう。あなたの検索スキルを磨くチャンスをうかがっているのは知っています。

________________________________

あなたの意図を誤解しているかもしれませんが、ユーザーがテキストボックスに日付を入力し、それをdatetimeとして解釈したい場合(負の数に興味がある場合はそうでないかもしれません)、私はいくつかの理由でこれが最善の方法であると確信しているわけではありません。

実際、問題の経済データには日付は含まれていません。「実績」、「予測」、「前回」、そして場合によっては「改訂」されたデータだけです。もちろん、B(billion)や%(percent)などの記号を入力するつもりもない。スペースなしの純粋な実数だけである。このアイデアは、私が「同時リリースインデックス」と呼んでいるものを計算することです。これは、同時に発表された一連の経済データを組み合わせて、一つのデータとして見ることを意味している。私は、すべての「実績」を1つの「実績」として、すべての「予測」を1つの「予測」として組み合わせ、組み合わせた「実績」と組み合わせた「予測」等の関係を見るために、このような計算をします。

 
macpee:
if((char1>47 && char1<58) || char1==46)
ところで、コード(ASCIIと思われる)のリストが見当たりません。
数字をハードコードしてはいけない。コードをセルフドキュメント化しましょう。
if((char1>='0' && char1<='9') || char1=='.')
文字定数 - 整数型 - データ型 - 言語の基本 - MQL4リファレンス
 
macpee:
実際には、問題の経済データには日付は含まれていない。「実績」、「予測」、「前回」、そして場合によっては「改訂」データだけである。もちろん、B(billion)、%(percent)などの記号を入力するつもりもない。スペースなしの純粋な実数だけである。このアイデアは、私が「同時リリースインデックス」と呼んでいるものを計算することです。これは、同時に発表された一連の経済データを組み合わせて、一つのデータとして見ることを意味している。私は、すべての「実績」を1つの「実績」として、すべての「予測」を1つの「予測」として組み合わせ、組み合わせた「実績」と組み合わせた「予測」等の関係を見るために、このような計算をします。

だから

  • 文字列を参照渡しにする
  • 空白を取り除く
  • ','を取り除く
  • が1つだけであることを確認 する
  • または'-'が最初の文字としてのみ表示されることを確認します。
  • 他のすべての文字が0から9の間の数字であることを確認します。

bool IsValidNumber(string &text)
  {
   StringReplace(text," ",NULL);
   StringReplace(text,",",NULL);
   int point_cnt = 0;
   for(int i=StringLen(text)-1; i>=0; i--)
     {
      int this_char = StringGetChar(text,i);
      if(this_char == '.')
        {
         point_cnt++;
         if(point_cnt>1)       return(false);
         if(StringLen(text)<2) return(false);
        }
      else if(this_char == '+' || this_char == '-')
        {
         if(i>0) return(false);
        }
      else if(this_char < '0' || this_char > '9') return(false);
     }
   return(true);
  }

もしtrueを返したら、その文字列を数値としてキャストすることができます。

 
honest_knave:

だから

  • 文字列を参照渡しにする
  • 空白を取り除く
  • ','を取り除く
  • が1つだけであることを確認する
  • または'-'が最初の文字としてのみ表示されることを確認します。
  • 他のすべての文字が0から9の間の数字であることを確認します。

bool IsValidNumber(string &text)
  {
   StringReplace(text," ",NULL);
   StringReplace(text,",",NULL);
   int point_cnt = 0;
   for(int i=StringLen(text)-1; i>=0; i--)
     {
      int this_char = StringGetChar(text,i);
      if(this_char == '.')
        {
         point_cnt++;
         if(point_cnt>1)       return(false);
         if(StringLen(text)<2) return(false);
        }
      else if(this_char == '+' || this_char == '-')
        {
         if(i>0) return(false);
        }
      else if(this_char < '0' || this_char > '9') return(false);
     }
   return(true);
  }

trueを返したら、その文字列を数字に変換することができます。

本当にややこしいのが好きなんですね 。実数の処理だけが目的なら、StringToDouble() と特殊ケース0の処理を使えばいい。