如何检查一个变量的内容是否是数字? - 页 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)实际上是零(0)。现在我试着增加句点的数量(.....),它仍然将其识别为数字。我们需要句号(...)的代码,以便在第一个句号被引用后,消除额外的句号(....)。
if((char1>47 && char1<58) || char1==46)
顺便说一下,我找不到代码的列表(我猜是ASCII)。

另一件事是如何输入负数。代码只需要在输入的开头捕捉到否定符号(-)。

此外,为了完善代码。它需要接受否定符号(-),即使是在数字的中间,如(45-20),并将其视为减法和评估,然后使用代码
int char1=StringGetChar(text,i);
来检查结果是否为Numeric。我们可以对所有四种基本的二进制操作都这样做。但这对我们现在并不重要。

整个想法是使 OBT_EDIT 的 OBJPROP_TEXT属性 接受经济日历数据,并将它们视为数字。这就是为什么一个内置的IsNumeric函数相当重要,以避免为它编写不必要的大代码。
 
macpee:
当然,句号(.)应该是数字,因为(.)被视为与句号和零(.0)相同的东西,而零(0)实际上是0。现在我试着增加句号的数量(.....),它仍然将其识别为数字。我们需要句号(...)的代码,以便在第一个句号被引用后,消除额外的句号(....)。
if((char1>47 && char1<58) || char1==46)
顺便说一下,我找不到代码的列表(我猜是ASCII)。

另一件事是如何输入负数。代码只需要在输入的开头捕捉到否定符号(-)。

此外,为了完善代码。它需要接受否定符号(-),即使是在数字的中间,如(45-20),并将其视为减法和评估,然后使用代码
int char1=StringGetChar(text,i);
来检查结果是否为Numeric。我们可以对所有四种基本的二进制操作都这样做。但这对我们现在并不重要。

整个想法是使 OBT_EDIT 的 OBJPROP_TEXT属性 接受经济日历数据,并将它们视为数字。这就是为什么一个内置的IsNumeric函数相当重要,以避免为其编写不必要的大型代码。
或者,一个解决方案是在IsNumeric检查后将字符串转换为双数。
 

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函数是相当重要的,以避免为它编写不必要的大代码。

虽然我可能误解了你的意图,但如果你想让用户在编辑框中输入日期,然后把它们解释为日期时间(如果你对负数感兴趣,可能就不是了),我不相信这是最好的方法,原因有很多。

 
honest_knave:

这里有回声吗?

________________________________

来吧,给它一个机会。我知道你一直渴望有机会磨练一下你的搜索技巧。

________________________________

虽然我可能误解了你的意图,但如果你想让用户在文本框中输入日期,然后将其解释为日期时间(如果你对负数感兴趣,可能就不是了),我不相信这是最好的方法,原因有很多。

事实上,有关的经济数据并不包括日期--只有 "实际"、"预测"、"以前 "和可能的 "修订 "数据。当然,我们也不打算输入符号,如B(代表十亿),%(代表百分比)等。只有纯实数,没有空格。这个想法是为了计算我所说的 "同时发布指数"。它的目的是结合一组同时发布的经济数据,并将它们视为一个数据。我将把所有的 "实际 "合并为一个 "实际",所有的 "预测 "合并为一个 "预测",等等,以便看到合并的 "实际 "和合并的 "预测 "等之间的关系。

 
macpee:
if((char1>47 && char1<58) || char1==46)
顺便说一下,我找不到代码的清单(ASCII,我猜)。
不要硬编码数字。让你的代码自带文件。
if((char1>='0' && char1<='9') || char1=='.')
字符常量 - 整数类型 - 数据类型 - 语言基础 - MQL4参考
 
macpee:
实际上,有关的经济数据并不包括日期--只有 "实际"、"预测"、"以前 "和可能的 "修订 "数据。当然,我们也不打算输入符号,如B(代表十亿),%(代表百分比)等。只有纯实数,没有空格。这个想法是为了计算我所说的 "同时发布指数"。它的目的是结合一组同时发布的经济数据,并将它们视为一个数据。我将把所有的 "实际 "合并为一个 "实际",所有的 "预测 "合并为一个 "预测",等等,以便看到合并的 "实际 "和合并的 "预测 "等之间的关系。

所以。

  • 通过引用传递字符串
  • 剥去空白处
  • 剥离','。
  • 检查'+'或'-'是否只作为第一个字符出现
  • 检查其他每个字符是否是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);
  }

如果它的返回值为真,你可以将该字符串转换为数字。

 
honest_knave:

所以。

  • 通过引用传递字符串
  • 剥去空白处
  • 剥离','。
  • 检查只有一个'.'
  • 检查'+'或'-'是否只作为第一个字符出现
  • 检查其他每个字符是否是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);
  }

如果它返回真,你就可以将该字符串转换为数字。

你真的很喜欢复杂化 。如果目标只是处理实数,可以使用StringToDouble() 和对特殊情况0的处理。