Bir değişkenin içeriğinin sayısal olup olmadığını nasıl kontrol edebilirim? - sayfa 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 );
  }  
//+------------------------------------------------------------------+
Örnek kodlarınız için teşekkürler. Ancak "IsNumeric" anahtar kelimeniz MQL4'e ait görünmüyor. Yanlışım varsa lütfen düzelt. Yine de kodunuz çok iyi çalışıyor ve bu, aradığım şeye mükemmel bir örnek. Teşekkür ederim.
 
macpee : Ancak "IsNumeric" anahtar kelimeniz MQL4'e ait görünmüyor. Yanlışım varsa lütfen düzelt.
Anahtar kelime değil, yukarıda sağladığı bir işlevdir .
 
whroeder1 :
Anahtar kelime değil, yukarıda sağladığı bir işlevdir .
Bana bak. Bilmeliydim. @whroeder1'e teşekkürler.
 
macpee :
Bana bak. Bilmeliydim. @whroeder1'e teşekkürler.
Tabii ki bir nokta (.) sayısal olmalıdır, çünkü (.) nokta ve sıfır (.0) ile aynı şey olarak kabul edilir, ki bu aslında sıfır (0)'dır. Şimdi nokta sayısını (.....) artırmayı denedim ve hala onu sayısal olarak tanıyor. İlk nokta alıntılandıktan sonra ek noktayı (....) ortadan kaldırmak için nokta (.) koduna ihtiyacımız var.
if ((char1> 47 && char1< 58 ) || char1== 46 )
Bu arada, kodun listesini bulamıyorum (ASCII, sanırım).

Başka bir şey de negatif sayıların nasıl girileceğidir. Kodun, yalnızca girişin başında olumsuzlama işaretini (-) yakalaması gerekir.

Ayrıca, kodu mükemmelleştirmek için. (45-20) gibi sayıların ortasında bile olumsuzlama sembolünü (-) kabul edip çıkarma işlemi gibi ele alıp değerlendirip kodu kullanması gerekir.
int char1= StringGetChar (text,i);
sonucun Sayısal olduğunu kontrol etmek için Bunu dört temel ikili işlemin tümü için yapabiliriz. Ama bu bizim için şu anda önemli değil.

Bütün fikir, OBT_EDIT'in OBJPROP_TEXT özelliğini ekonomik takvim verilerini kabul edecek ve onlara oldukları gibi davranacak şekilde yapmaktır. Bu nedenle, IsNumeric'in yerleşik bir işlevi, onun için gereksiz yere büyük kodlar yazmaktan kaçınmak için oldukça önemlidir.
 
macpee :
Tabii ki bir nokta (.) sayısal olmalıdır, çünkü (.) nokta ve sıfır (.0) ile aynı şey olarak kabul edilir, ki bu aslında sıfır (0)'dır. Şimdi nokta sayısını (.....) artırmayı denedim ve hala onu sayısal olarak tanıyor. İlk nokta alıntılandıktan sonra ek noktayı (....) ortadan kaldırmak için nokta (.) koduna ihtiyacımız var.
if ((char1> 47 && char1< 58 ) || char1== 46 )
Bu arada, kodun listesini bulamıyorum (ASCII, sanırım).

Başka bir şey de negatif sayıların nasıl girileceğidir. Kodun, yalnızca girişin başında olumsuzlama işaretini (-) yakalaması gerekir.

Ayrıca, kodu mükemmelleştirmek için. (45-20) gibi sayıların ortasında bile olumsuzlama sembolünü (-) kabul edip çıkarma işlemi gibi ele alıp değerlendirip kodu kullanması gerekir.
int char1= StringGetChar (text,i);
sonucun Sayısal olduğunu kontrol etmek için Bunu dört temel ikili işlemin tümü için yapabiliriz. Ama bu bizim için şu anda önemli değil.

Bütün fikir, OBT_EDIT'in OBJPROP_TEXT özelliğini ekonomik takvim verilerini kabul edecek ve onlara oldukları gibi davranacak şekilde yapmaktır. Bu nedenle, IsNumeric'in yerleşik bir işlevi, onun için gereksiz yere büyük kodlar yazmaktan kaçınmak için oldukça önemlidir.
Ya da belki bir çözüm, IsNumeric kontrolünden sonra dizeyi ikiye katlamaktır.
 

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

Başka bir şey de negatif sayıların nasıl girileceğidir. Kodun, yalnızca girişin başında olumsuzlama işaretini (-) yakalaması gerekir.

Burada bir yankı var mı?

dürüst_knave :

Evet, öyle bir şey.

Şu konularda dikkatli olmanız gerekir:

  • Birden çok ondalık nokta (geçerdi ama geçmemeli)
  • + ve - sembollerinin kullanımı (geçemez ama gerekir)
  • binlik ayırıcı veya ondalık nokta olarak kullanılması (geçemez, ancak gerekir)
  • Başka karakter içermeyen tek bir ondalık nokta (geçerdi ama geçmemeli)
  • Oyuncu kadrosunun kapasitesini aşan sayılar
  • boşluklar

________________________________

macpee :

Bu arada, kodun listesini bulamıyorum (ASCII, sanırım).

Hadi, bir şans ver. Arama becerilerini geliştirmek için bir fırsat için can attığını biliyorum.

________________________________

macpee :

Bütün fikir, OBT_EDIT'in OBJPROP_TEXT özelliğini ekonomik takvim verilerini kabul edecek ve onlara oldukları gibi davranacak şekilde yapmaktır. Bu nedenle, IsNumeric'in yerleşik bir işlevi, onun için gereksiz yere büyük kodlar yazmaktan kaçınmak için oldukça önemlidir.

Niyetinizi yanlış anlamış olsam da, kullanıcının bir düzenleme kutusuna tarih girmesini ve ardından bunları tarih saatleri olarak yorumlamasını istiyorsanız (muhtemelen negatif sayılarla ilgileniyorsanız değil), bunun en iyi yaklaşım olduğuna ikna olmadım. sayıda neden.

 
honest_knave :

Burada bir yankı var mı?

________________________________

Hadi, bir şans ver. Arama becerilerini geliştirmek için bir fırsat için can attığını biliyorum.

________________________________

Niyetinizi yanlış anlamış olsam da, kullanıcının bir metin kutusuna tarih girmesini ve ardından bunları tarih saatleri olarak yorumlamasını istiyorsanız (muhtemelen negatif sayılarla ilgileniyorsanız değil), bunun en iyi yaklaşım olduğuna ikna olmadım. sayıda neden.

Aslında söz konusu ekonomik veriler tarihleri içermez - sadece 'gerçek', 'tahmin', 'önceki' ve muhtemelen 'gözden geçirilmiş' veriler. Elbette B(milyar için), %(yüzde için) vb. gibi sembolleri de girmek niyetinde değiliz. Sadece boşluksuz saf gerçek sayılar. Buradaki fikir, "Eşzamanlı Yayın İndeksi" dediğim şeyi hesaplamak. Aynı anda yayınlanan bir dizi ekonomik veriyi birleştirmek ve bunları tek bir veri olarak görmek içindir. Birleşik "gerçek" ve birleşik "tahmin" vb. arasındaki ilişkiyi görmek için tüm "gerçekleri" tek bir "gerçek" olarak, tüm "tahminleri" tek bir "tahmin" olarak vb. birleştirirdim.

 
macpee :
if ((char1> 47 && char1< 58 ) || char1== 46 )
Bu arada, kodun listesini bulamıyorum (ASCII, sanırım).
Kod numaralarını sabit tutmayın. Kodunuzu kendi kendine belgeleyin.
if ((char1>= '0' && char1<= '9' ) || char1== '.' )
Karakter Sabitleri - Tamsayı Türleri - Veri Türleri - Dil Temelleri - MQL4 Referansı
 
macpee :
Aslında söz konusu ekonomik veriler tarihleri içermez - sadece 'gerçek', 'tahmin', 'önceki' ve muhtemelen 'gözden geçirilmiş' veriler. Elbette B(milyar için), %(yüzde için) vb. gibi sembolleri de girmek niyetinde değiliz. Sadece boşluksuz saf gerçek sayılar. Buradaki fikir, "Eşzamanlı Yayın İndeksi" dediğim şeyi hesaplamak. Aynı anda yayınlanan bir dizi ekonomik veriyi birleştirmek ve bunları tek bir veri olarak görmek içindir. Birleşik "gerçek" ve birleşik "tahmin" vb. arasındaki ilişkiyi görmek için tüm "gerçekleri" tek bir "gerçek" olarak, tüm "tahminleri" tek bir "tahmin" olarak vb. birleştirirdim.

Böyle:

  • Dizeyi referansa göre iletin
  • Boş alanları ayıklayın
  • ',' işaretini çıkarın
  • '+' veya '-' yalnızca ilk karakter olarak göründüğünü kontrol edin
  • Diğer her karakterin 0 ile 9 arasında bir sayı olduğunu kontrol edin

Örneğin

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 döndürürse, dizeyi bir sayı olarak yayınlayabilirsiniz.

 
honest_knave :

Böyle:

  • Dizeyi referansa göre iletin
  • Boş alanları ayıklayın
  • ',' işaretini çıkarın
  • Yalnızca bir tane '.' olup olmadığını kontrol edin.
  • '+' veya '-' yalnızca ilk karakter olarak göründüğünü kontrol edin
  • Diğer her karakterin 0 ile 9 arasında bir sayı olduğunu kontrol edin

Örneğin

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 döndürürse, dizeyi bir sayı olarak yayınlayabilirsiniz.

Komplikasyonu gerçekten seviyorsun . Amaç yalnızca gerçek sayıları işlemekse, StringToDouble() ve özel durum 0'ın işlenmesini kullanın.
Neden: